Lisp Language Elements

 

Overview

The Lisp language is characterized by functions, macros, special forms, and lexical forms. These functions, macros, special forms, and lexical forms contain everything from basic control flow operators to language keywords. All of the basic language elements of AIS Lisp are contained in this chapter.

All Lisp macros, special forms, and lexical forms are understood only by the Lisp compiler.

Lisp, heavily influenced by the functional programming paradigm, is a language composed entirely of function calls. Each function call is inclosed in parentheses (function ...agruments...). It is this focus on the parenthetically enclosed function call which gives Lisp its multiplicity of parens.

The best pocket introduction to the essential elements of AIS Lisp is the following table of Lisp essential flow of control language elements.

(ref ... ) Access statement
(setq ... ) Assignment statement
(if ... then ... else ... ) Conditional statement
(loop ... ) Iteration statement
(while ... ) Iteration statement
(cond ... case ... case ... ) Conditional case statement
(goto ... ) Transfer of control statement
(defclass ... ) Class (user defined) declaration statement
(lambda ... ) Agent(function) building statement
(defun ... ) Agent(function) declaration statement
(defchild ... ) Agent(function) declaration statement
(defriend ... ) Agent(function) declaration statement
(deforphan ... ) Agent(function) declaration statement
(defmethod ... ) Agent(method) declaration statement
(defvm ... ) Agent(virtual machine) declaration statement
regs:(...) Agent(register) declaration statement
vars:(...) Agent(variable) declaration statement
svars:(...) Object(variable) declaration statement
pvars:(...) Agent(variable) declaration statement
cvars:(...) Agent(variable) declaration statement

Agent Declaration

The lambda special form creates and returns an instance of an Agent object. Each agent is an executable software object which is storable as a fundamental unit of data in an AIS repository and can be mobile between copies of Agent Information Server across the Internet. AIS Lisp provides several ways to declare an Agent. The lambda function supports the creation of unbound-unnamed agents. There are multiple ways of declaring bound-named agents as follows.

defun Declaration of globally bound and named agent. May be declared inside the body of another agent declaration. If declared inside another parent agent declaration, this agent automatically becomes the child of its parent agent. The child agent will be bound to its name in the Pv persistent storage Structure of the parent agent. The child's Pv and Cv persistent storage Structures will be identical (the exact same objects) as its parent agent.
defchild Declaration of a child agent to a globally bound and named parent agent. Must be declared outside the body of the parent agent declaration. The parent agent must already have declared a pvars variable of the same name as declared in this child agent. The child agent will be bound to its name in the Pv persistent storage Structure of the parent agent. The child's Pv and Cv persistent storage Structures will be identical (the exact same objects) as its parent agent.
defriend Declaration of a friend agent to a globally bound and named parent agent. Must be declared outside the body of the parent agent declaration. The parent agent must already have declared a pvars variable of the same name as declared in this friend agent. The friend agent will be bound to its name in the Pv persistent storage Structure of the parent agent. The parent's Pv persistent storage Structure will be unknown to the friend agent. The friend's Pv persistent storage Structure will be identical to the Cv persistent storage Structure of its parent agent. The friend's Cv persistent storage Structure will be unknown to the parent agent.
deforphan Declaration of an orphan agent to a globally bound and named parent agent. Must be declared outside the body of the parent agent declaration. The parent agent must already have declared a pvars variable of the same name as declared in this orphan agent. The orphan agent will be bound to its name in the Pv persistent storage Structure of the parent agent. The parent's Pv and Cv persistent storage Structures will be unknown to the orphan agent. The orphan's Pv and Cv persistent storage Structures will be separate and distinct from those of its parent agent.
defmethod Declaration of a bound and named method agent to an owner data type (Object Oriented Programming Paradigm). The owner data type must already have been declared. The method agent will be bound to its name in the methods Dictionary associated with its owner data type.
defmacro Declaration of globally bound and named Lisp macro agent. Will automatically be recognized by the morph and compile functions during compilation.
defvm Declaration of a globally bound and named Agent virtual machine. Can be assigned as the virtual machine of any agent, and will be responsible for controling the agent's behavior.

Each agent declaration contains the declaration of variables (including argument variables), the declaration of agent interfaces, and any agent event keywords.

Variable Declarations

AIS Lisp supports the declaration of local variables. There are five categories of local variables for each agent.

The vars, pvars, and cvars local variable allocations may include initialization specifications along with their declarations. The regs local variable allocations may include data type specifications along with their declarations.

    (defun foo(n) ;; Variable n is an argument variable.

        vars:(x Number:y) ;; y and y are temporary variables.

        pvars:((a 20)) ;; Variable a is a persistent variable initialized to type Word with a value of 20.

        cvars:(b) ;; Variable b is a persistent variable uninitialized defaulted to Word type.

        regs:(Integer:myReg) ;; Variable myReg is a microchip register variable typed as Integer.

        true)

An Agent Information Server Agent may be defined, with a definite list (fixed) or an indefinite list of arguments. Ellipses (...) at the end of the argument list indicate the function has indefinite arguments. At run time, the Agent's actual arguments are bound to the specified formal definite arguments respectively. An error is generated if there are too few arguments in the definite argument list. If the number of actual arguments exceeds the number of definite arguments, and the function has been defined as having indefinite arguments, the excess arguments can only be accessed via the argCount and argFetch functions at run time. When called, the Agent receives its arguments on the stack. The arguments are received and bound to the proper arguments.

 

Interface Declarations

AIS Lisp supports the declaration of agent interfacesas well as the declaration of event keywords. The keyword faces: declares the interfaces feature Structure of the Agent. The features are specified as list constants, faces:((name Alice)), the listed feature is initialized to the value specified.

The keyword doomed: declares that the Agent is to be evaluated, by the garbage collector, when the Agent is doomed. The Agent?s EvalWhenDoomed element is set to true. The Agent is always evaluated, by the garbage collector, with no arguments.

    (defun foo() ;; Agent is declared with no argument variables.

        faces:((English true) (French false)) ;; Declaration of English and French interface protocols.

        Doomed: ;; This agent will be executed just before it is destroyed.

        true)

 

Type:       Special Form

 

Syntax examples

 

       (defun name(arguments) variables interfaces body)

       (defchild parent:name(arguments) variables interfaces body)

       (defriend parent:name(arguments) variables interfaces body)

       (deforphan parent:name(arguments) variables interfaces body)

       (defmethod typeSymbol:name(arguments) variables interfaces body)

       (defmacro name(arguments) variables interfaces body)

       (defvm name(arguments) variables interfaces body)

 

Arguments


name The name to which the agent is to be bound.
arguments The list of argument variable declarations.
variable declarations The list of local variable declarations.
body The Lisp expressions which make up the execution instructions for the agent.
Returns An executable agent object.

parent The name of the parent agent into which the agent is to be bound.
name The name to which the agent is to be bound.
arguments The list of argument variable declarations.
variable declarations The list of local variable declarations.
body The Lisp expressions which make up the execution instructions for the agent.
Returns An executable agent object.

typeSymbol The name of the owner data type into whose method list the agent is to be bound.
name The name to which the agent is to be bound.
arguments The list of argument variable declarations.
variable declarations The list of local variable declarations.
body The Lisp expressions which make up the execution instructions for the agent.
Returns An executable agent object.

 

When To Use

Use the lambda special form and other agent declaration forms when an Agent is to be created for use in your application program.

 

Example 1

These examples demonstrate some simple properties of the lambda special form. Here the lambda returns a simple Agent.

    (lambda(X) (+ X X))Returns   #<Agent 392>

Here a simple Agent is declared bound to a global variable.

    (defun foo(X) (+ X X))Returns   #<Agent 312>

Here the Agent is invoked with the argument 4.

    (foo 4)Returns   8

Here the Agent is immediately invoked with the argument 4.

    ((lambda(X) (+ X X)) 4)Returns   8

 

Example 2

Here a slightly more complex Agent which is declared bound to a global variable.

    (defun sumNums(X ...)

       vars:(Z)

       (setq Z X)

       (loop for i from 1 to (1+ (argCount)) do

          (setq Z (+ Z (argFetch i)))))

Here the Agent is invoked with the arguments 4 5 and 71.

    (sumNums 4 5 71)   Returns   80

 

Example 3

This example defines an Agent named foo with a child Agent named sum.

    (defun foo(x)

       pvars:(y)

       (defun sum(x) (+ x y))

       (setq y x))

Here we invoke the parent agent foo.

    (foo 9)   Returns   9

Here we invoke the child agent sum.

    (foo.sum 2)   Returns   11

 

Notes & Hints

The scope of variables in nested agents depends upon the following Lisp compilation rules: Nested agents do not share either their argument or their temporary variables. The argument and the temporary variables are always limited in scope to the immediate Agent object. A nested Agent both shares and extends the persistent variables (pvars) of its parents. When a variable reference is encountered, the Lisp compiler first searches the local agent's arguments for a match, then the searches the local agent's temporary variables (vars) for a match, finally searches the agent's extended persistent variables (pvars) and then the (cvars) for a match. A referenced variable, without a match, always refers to the global value of the variable.

Built-in AIS Functions and Objects

All of the built-in AIS functions and objects are available to Lisp programs. Functions such as append, left, avg, sqrt, etc. are all available to Lisp programs. Objects such as Vector, String, Structure, Repository, etc. are all available to Lisp programs. Also available to all Lisp programs is a rich library of native data types. In order to benefit from the full power of the AIS environment, the Lisp programmer should become familiar with the many libraries of functions, macros, and object types available.

 

The following reference guides may be of some help.

Accessing with ref

The ref function is the fundamental access statement of Lisp. The ref function supports both direct referencing and indexed referencing of elements within an object. The ref function must always be passed one variable argument; and, can be passed one, two, or three, index arguments. In each case The ref function returns the result of referencing the variable with one, two, or three index arguments.

 

Type:       function

 

Syntax examples

 

       (ref variable)

       (ref variable index1)

       (ref variable index1 index2)

       (ref variable index1 index2 index3)

 

Arguments


variable The target of the reference attempt (the ultimate behavior of ref is dependent upon the data type of the target).
index1 (Optional) First index argument.
index2 (Optional) Second index argument.
index3 (Optional) Third index argument.

 

When To Use

Use the ref function when indexed referencing of an AIS object is essential to the correct operation of your program.

 

Example 1

Here are just a few sample object retrievals using the ref function.

 

    (setq x (new Vector:3 45 -6 78)) ;; Set the newly created vector object into the variable x.

    (ref x 2)   Returns   78

    (ref x 0)   Returns   45

    (setq x (new Structure: A: 45 B: -6 C: 78)) ;; Set the Structure object into the variable x.

    (ref x C:)   Returns   78

    (ref x A:)   Returns   45

    (ref x 2 1)   Returns   78

    (setq x "Hello World") ;; Set the string "Hello World" into the variable x.

    (ref x 1)   Returns   #\e

    (ref x 6)   Returns   #\W

 

Notes & Hints

Refer to the appropriate object data type reference guide to determine the effect of the ref function on that specific type or even what types of indices the ref function can take. For String objects refer to the String Object Reference Guide, For Vector objects refer to the Vector Object Reference Guide, For Dictionary objects refer to the Dictionary Object Reference Guide, etc.

Assigning with setq

Overview

The setq special form is the fundamental assignment statement of Lisp. The setq special form supports both direct assignment and indexed assignment of elements within an object. The setq special form must always be passed one receiver argument, and one new value argument; and, can be passed one, two, or three, index arguments. In each case The setq special form returns the result of assigning the new value argument to the receiver argument with one, two, or three index arguments.

 

Type:       special form

 

Syntax examples

 

       (setq receiver newValue)

       (setq (ref receiver index1) newValue)

       (setq (ref receiver index1 index2) newValue)

       (setq (ref receiver index1 index2 index3) newValue)

       (set receiver index1 newValue)

       (set receiver index1 index2 newValue)

       (set receiver index1 index2 index3 newValue)

 

Arguments


receiver The target of the assignment attempt (the ultimate behavior of setq is dependent upon the data type of the receiver).
index1 (Optional) First index argument.
index2 (Optional) Second index argument.
index3 (Optional) Third index argument.
newValue The new value to be assigned to the receiver.

 

When To Use

Use the setq special form when indexed assignment of an AIS object is essential to the correct operation of your program.

 

Example 1

Here are just a few sample object assignments using the setq special form.

 

    (setq x (new Vector:3 45 -6 78)) ;; Set the newly created vector object into the variable x.

    (set x 2 20)   Returns   #(45 -6 20)

    (setq (ref x 0) -65)   Returns   #(-65 -6 20)

    (setq x (new Structure: A: 45 B: -6 C: 78)) ;; Set the Structure object into the variable x.

    (setq (ref x C:) 22)   Returns   #{A 45 B -6 C 22}

    (set x A: 16)   Returns   #{A 16 B -6 C 22}

    (set x 1 0 X:)   Returns   #{A 16 X -6 C 22}

    (setq x "Hello World") ;; Set the string "Hello World" into the variable x.

    (set x 1 #\E)   Returns   "HEllo World"

    (setq (ref x 6) #\w)   Returns   "HEllo world"

 

Notes & Hints

Refer to the appropriate object data type reference guide to determine the effect of the setq special form on that specific type or even what types of indices the setq special form can take. For String objects refer to the String Object Reference Guide, For Vector objects refer to the Vector Object Reference Guide, For Dictionary objects refer to the Dictionary Object Reference Guide, etc.

Bracket Operator []

The Bracket Operator [ ] supports both setting and referencing indexed elements within an object in AIS Lisp. The bracket operator, used for reference, is the equivalent of the ref built-in function. The bracket operator, used for assignment, is the equivalent of the setq special form.

 

Type:       Lexical

 

Syntax examples

 

       variable[index]

       (setq variable[index] newValue)

 

Equivalence


x[5] is identical to (ref x 5)
(setq x[2] "Hello") is identical to (setq (ref x 0) "Hello")

 

When To Use

Use the bracket operator when writing out the full equivalent setq or ref expressions would be too cumbersome or would make the Lisp program less readable.

 

Example 1

Here are just a few sample object retrievals and settings using the bracket operator.

 

    (setq x (new Vector:3 45 -6 78)) ;; Set the newly created vector object into the variable x.

    x[2]   Returns   78

    x[0]   Returns   45

    (setq x[0] 26)   Returns   #(26 -6 78)

    (setq x "Hello World") ;; Set the string "Hello World" into the variable x.

    x[1]   Returns   #\e

    x[6]   Returns   #\W

    (setq x[0] #\h)   Returns   "hello World"

 

Notes & Hints

Refer to the appropriate object data type reference guide to determine the effect of the bracket operator on that specific type or even what types of indices the bracket operator can take. For String objects refer to the String Object Reference Guide, For Vector objects refer to the Vector Object Reference Guide, For Dictionary objects refer to the Dictionary Object Reference Guide, etc.

Dot Operator .

The Dot Operator . supports both setting and referencing indexed elements within an object in AIS Lisp. The dot operator, used for reference, is the equivalent of the ref built-in function. The dot operator, used for assignment, is the equivalent of the setq special form.

 

Type:       Lexical

 

Syntax examples

 

       variable.indexSymbol

       (setq variable.indexSymbol newValue)

 

Equivalence


x.A is identical to (ref x A:)
(setq x.C "Hello") is identical to (setq (ref x C:) "Hello")

 

When To Use

Use the dot operator when writing out the full equivalent setq or ref expressions would be too cumbersome or would make the Lisp program less readable.

 

Example 1

Here are just a few sample object retrievals and settings using the dot operator.

 

    (setq x (new Structure: A: 45 B: -6 C: 78)) ;; Set the newly created Structure object into the variable x.

    x.C   Returns   78

    x.A   Returns   45

    (setq x.A 26)   Returns   #{A 26 B -6 C 78}

    (setq x.B 0)   Returns   #{A 26 B 0 C 78}

 

Notes & Hints

Refer to the appropriate object data type reference guide to determine the effect of the dot operator on that specific type or even what types of indices the bracket operator can take. For String objects refer to the String Object Reference Guide, For Vector objects refer to the Vector Object Reference Guide, For Dictionary objects refer to the Dictionary Object Reference Guide, etc.

Offset Addressing

The offset function returns the byte offset, from the start of the specified basis object basis, when computed using the specified constant indices index1, index2, index3. The offset function operates on a number of object types and can accept from one to three indices depending upon the type of basis object. The offset function is an important tool in supporting direct offset addressing using AIS Lisp registers addressing.

The offset function is called automatically, by the compiler, when an AIS Lisp register variable is indexed by a constant offset expression, using the bracket operator such as: register[:integer:], register[basis(name)], register[basis(index1)], register[basis(index1,index2)], or register[basis(index1,index2,index3)]. AIS Lisp treats each register offset expression as a single compound variable name. Therefore, there can be absolutely NO whitespace between any of the parts of the register offset expression. It should also be noted that AIS Lisp only supports register offsets of up to 32,767 bytes.

                vars:((employee #{decl| (Name "John Doe") (Number:Salary 23450.00)}))

                regs:(NumPointer:ptr)

                (setq ptr employee)     ;; Loads register ptr with the address of the employee Structure.

                (+= ptr[employee(Salary)] 200.0)     ;; Adds 200 to Salary, using direct offset addressing from the ptr register.

 

Type:       Function

 

Syntax examples

 

       (offset basis index1)
       (offset basis index1 index2)
       (offset basis index1 index2 index3)
       register[:integer:]
       register[basis(name)]
       register[basis(index1)]
       register[basis(index1,index2)]
       register[basis(index1,index2,index3)]

 

Arguments


basis The specified basis object to be referenced via direct offset addressing.
name (Mandatory) The field name from which to compute the direct offset address.
Returns The direct offset address, from the start of the basis object, for the indices specified.

basis The specified basis object to be referenced via direct offset addressing.
index1 (Mandatory) The first numeric index from which to compute the direct offset address.
index2 (Optional) The second numeric index from which to compute the direct offset address.
index3 (Optional) The third numeric index from which to compute the direct offset address.
Returns The direct offset address, from the start of the basis object, for the indices specified.

 

When To Use

The offset function is an important tool in supporting direct offset addressing using AIS Lisp registers addressing.

The offset function operates on a number of object types and can accept a number of different constant indices, as follows:

 

Example 1

Here follows a simple example of AIS Lisp offset addressing in action.

      vars:((complex #{Real 2134.2 Imagine 23450.00}))
      regs:(NumPointer:ptr)
      (setq ptr complex)     ;; Loads register ptr with the address of the complex Structure.
      (+= ptr[complex(Real)] 200.0)     ;; Adds 200 to the real part of complex.
      (+= ptr[complex(Imagine)] 1540.0)     ;; Adds 200 to the imaginary part of complex.

 

Example 2

Here follows a simple example of AIS Lisp offset addressing for Number Matrices.

      vars:((gauss #(NumMat[2 2 2]| 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0)))
      regs:(NumPointer:ptr)
      (setq ptr gauss)     ;; Loads register ptr with the address of the gauss Matrix.
      (setq ptr[gauss(1 0 1)] .45)     ;; Moves .45 into the [1 0 1]th element of the matrix.

 

Notes & Hints

The offset function is an important tool for supporting direct register offset addressing in AIS Lisp.

Circumflex Operator ^

The Circumflex Operator ^ preceding a symbol references a global variable value even in contexts where there are local variable naming conflicts. The AIS Lisp ^ operator uses the getGlobalValue function to return the global value of the specified symbol argument. The circumflex operator ^name is the equivalent of the (getGlobalValue name:) function. Also the circumflex operator ^name has a similar effect as the |Gv:name| symbolic form.

 

Type:       Lexical

 

Syntax examples

 

       ^variable

 

       |Gv:variable|

 

Equivalence


^name is identical to (getGlobalValue name:)
^name has a similar effect as |Gv:name|

 

When To Use

Use the circumflex operator when writing out the full equivalent (getGlobalValue name:) expression would be too cumbersome or would make the Lisp program less readable, or use the |Gv:name| symbolic form to achieve the same effect without a function call.

 

Example

Here are just a few sample globals retrievals using the circumflex operator.

 

    (setq x (new Structure: A: 45 B: -6 C: 78)) ;; Set the Structure object into the global variable x.

    ((lambda(x) ^x) 2)   Returns   #{A 45 B -6 C 78}

    ((lambda(x) |Gv:x|) 2)   Returns   #{A 45 B -6 C 78}

    ((lambda(x) x) 2)   Returns   2

 

Notes & Hints

Use the circumflex operator only as shorthand notation for the (getGlobalValue name) function, or use the |Gv:name| symbolic form to achieve the same effect without a function call.

Quote Operator '

The Quote Operator ' preceding a list or symbol converts the list or symbol into a list or symbol constant. The AIS Lisp ' is the short hand equivalent of the quote special form.

 

Type:       Lexical

 

Syntax examples

 

       'symbol

       '(...list...)

 

Equivalence


'thing is identical to (quote thing)

 

When To Use

Use the quote operator when writing out the full equivalent quote expression would be too cumbersome or would make the Lisp program less readable.

 

Example 1

Here are just a few examples of the quote operator in action.

 

    (defun foo(x) (length x))   Returns   #<Agent 291>

    (setq x (new Vector: 3 1 2 3))   Returns   #(1 2 3)

    x   Returns   #(1 2 3)

    'x   Returns   x

    (foo x)   Returns   3

    (foo 'x)   Returns   1

    '(foo x)   Returns   (foo x)

 

Notes & Hints

Use the quote operator only as shorthand notation for the quote special form.

Colon Operator :

The Colon Operator : suffixing a symbol always converts the symbol into a symbolic constant. Also symbols enclosed in vertical bars |I am a compound symbol|: can be converted into symbolic constants using the colon operator. The AIS Lisp name: is the short hand equivalent of the (quote name) special form.

Using the colon operator on a symbol at the head of a list can be used as short hand to send a message to a class instance. The AIS Lisp (msg: self) is the short hand equivalent of the (send msg: self) method invocation.

 

Type:       Lexical

 

Syntax examples

 

       name:

       |I am a compound symbol|:

       (msg: self)

 

Equivalence


name: is identical to (quote name)
(msg: self) is identical to (send msg: self)

 

When To Use

Use the colon operator when writing out the full equivalent (quote name) or (send msg: self) expressions would be too cumbersome or would make the Lisp program less readable.

 

Example

Here are some examples of the colon operator in action.

 

    (defclass foo() svars:(Number:x Vector:y) (defun new(self) (setq y (new Vector: 3 1 2 3))) true)

    (defmethod foo:len(self) (length y))

    (setq x (new foo))

    (len: x)   Returns   3

    x:   Returns   x

    (length x)   Returns   2

    (length x:)   Returns   1

 

Notes & Hints

Use the colon operator as shorthand notation for the (quote name) special form, or use the colon operator as shorthand notation sending a message to a class instance.

At Operator @

The At Operator @ infixing a compound name, converts the compound name into a member macro invocation. The AIS Lisp parent@name is the short hand equivalent of the (refmacro parent name) special form. Using the @ Operator on a symbol at the head of a list can be used to invoke a member macro during compilation.

 

Type:       Lexical

 

Syntax examples

 

       (parent@name)

       (parent.child@name)

       (parent.child[2]@name)

 

Equivalence


parent@name is identical to (refmacro parent name)

 

When To Use

Use the @ operator when writing out the full equivalent (refmacro parent name) expression would be too cumbersome or would make the Lisp program less readable.

 

Example

Here is an example of the colon operator in action.

 

    (defun foo(x) pvars:(v len) (setq v x))

    (defmacro foo:len(self) (macroReplace self '(length %1)))

    (setq x (new Vector: 3 1 2 3))

    (foo@len x)   Returns   3

 

Math Operators + - * /

The Math Operators + - * / support the basic arithmetic operations of add (+), subtract (-), multiply (*), and divide (/). Each operator is treated as a function call (as is everything else in Lisp). Each math operator must have one argument, and may have up to nineteen (19) optional additional arguments.

The add (+) operator returns to total of all its numeric arguments. The subtract (-) operator returns the negative of the first argument (if only one argument was passed), and the difference between the first argument and the total of all remaining arguments (if more than one argument was passed). The multiply (*) operator returns the product of all its numeric arguments. The divide (/) operator returns the inverse of the first argument (if only one argument was passed), and the quotient of the first argument and the product of all remaining arguments (if more than one argument was passed).

 

Type:       Function

 

Syntax examples

 

       (+ number ... )

       (- number ... )

       (* number ... )

       (/ number ... )

 

Arguments


number (Mandatory) the first number to be operated upon
number (Optional) up to nineteen (19) additional numbers to be operated upon

 

When To Use

Use the math operators when artithmetic computations are essential to the success of your program.

 

Example 1

Here are just a few sample arithmetic computations using the math operators.

 

    (setq x (+ 10 20))Returns   30

    (setq x (/ x 15))Returns   2

    (setq x (- (* 15 x) 5 4 3 2 1))Returns   0

    (setq x (* 5 4 3 2 1))Returns   120

 

Notes & Hints

Use the math operators to return the results of arithmetic calculations.

Math Operators + - * /

The Math Operators + - * / support the basic arithmetic operations of add (+), subtract (-), multiply (*), and divide (/). Each operator is treated as a function call (as is everything else in Lisp). Each math operator must have one argument, and may have up to nineteen (19) optional additional arguments.

The add (+) operator returns to total of all its numeric arguments. The subtract (-) operator returns the negative of the first argument (if only one argument was passed), and the difference between the first argument and the total of all remaining arguments (if more than one argument was passed). The multiply (*) operator returns the product of all its numeric arguments. The divide (/) operator returns the inverse of the first argument (if only one argument was passed), and the quotient of the first argument and the product of all remaining arguments (if more than one argument was passed).

 

Type:       Function

 

Syntax examples

 

       (+ number ... )

       (- number ... )

       (* number ... )

       (/ number ... )

 

Arguments


number (Mandatory) the first number to be operated upon
number (Optional) up to nineteen (19) additional numbers to be operated upon

 

When To Use

Use the math operators when artithmetic computations are essential to the success of your program.

 

Example 1

Here are just a few sample arithmetic computations using the math operators.

 

    (setq x (+ 10 20))Returns   30

    (setq x (/ x 15))Returns   2

    (setq x (- (* 15 x) 5 4 3 2 1))Returns   0

    (setq x (* 5 4 3 2 1))Returns   120

 

Notes & Hints

Use the math operators to return the results of arithmetic calculations.

Math Assignors += -= *= /=

The Math Assignors += -= *= /= support the basic arithmetic operations of add (+), subtract (-), multiply (*), and divide (/). Each operator is treated as a function call (as is everything else in Lisp). Each math assignor must have exactly two arguments. The first argument must be a variable which is the target assignor of the operation, and the second argument must be a numeric value which is the assignee.

The add (+=) assignor assigns the total of the target and the argument back into the target. The subtract (-=) assignor assigns the difference of the target and the argument back into the target. The multiply (*=) assignor assigns the product of the target and the argument back into the target. The divide (/=) assignor assigns the quotient of the target and the argument back into the target.

 

Type:       Macro

 

Syntax examples

 

       (+= variable number)

       (-= variable number)

       (*= variable number)

       (/= variable number)

 

Arguments


variable The target to be assigned with the final result.
number The numeric argument to be added to, subtracted from, multiplied by, or divided into the target.

 

When To Use

Use the math assignors when artithmetic computations are essential to the success of your program, and the long hand equivalent setq special forms would be to cumbersome or would make your program difficult to read.

 

Example 1

Here are just a few sample arithmetic computations using the math assignors.

 

    (setq x (+ 10 20))Returns   30

    (+= x 15)Returns   45

    (-= x (+ 5 4 3 2 1))Returns   30

    (*= x 2)Returns   60

    (/= x 2)Returns   60

 

Notes & Hints

The math assignors are all equivalent to standard (setq ...) special forms. For instance, (+= n 20) is equivalent to (setq n (+ n 20))

Math Incrementors ++ --

The Math Incrementors ++ -- support the basic arithmetic operations of increment (++), and decrement (--). Each operator is treated as a function call (as is everything else in Lisp). Each math incrementor must have exactly one argument, a variable which is the target assignor of the moperation. The increment (++) incrementor assigns the total of the target and the number 1 back into the target. The decrement (--) incrementor assigns the difference of the target and the number 1 back into the target.

 

Type:       Macro

 

Syntax examples

 

       (++ variable)

       (-- variable)

 

Arguments


variable The target to be incremented or decremented.

 

When To Use

Use the math incrementors when artithmetic computations are essential to the success of your program, and the long hand equivalent setq special forms would be to cumbersome or would make your program difficult to read.

 

Example 1

Here are just a few sample arithmetic computations using the math incrementors.

 

    (setq x (+ 10 20))Returns   30

    (++ x)Returns   31

    (-- x)Returns   30

 

Notes & Hints

The math incrementors are all equivalent to standard (setq ...) special forms. For instance, (++ n) is equivalent to (setq n (+ n 1))

Relational Operators < <= = == <> >= >

The Relational Operators < <= = == <> >= > support the basic comparison operations of less than (<), less than or equal (<=), equal (=), isIdentical (==), not equal (<>), greater than or equal (>=), and greater than (>). Each comparison operator is treated as a function call (as is everything else in Lisp). Each comparison operator must have two arguments.

The less than (<) operator returns true if arg1 is less than arg2. The less than or equal (<=) operator returns true if arg1 is less than or equal to arg2. The equal (=) operator returns true if arg1 is equal to arg2. The isIdentical (==) operator returns true if arg1 is identical to arg2. The not equal (<>) operator returns true if arg1 is not equal to arg2. The greater than or equal (>=) operator returns true if arg1 is greater than or equal to arg2. The greater than (>) operator returns true if arg1 is greater than arg2.

 

Type:       Function

 

Syntax examples

 

       (< value1 value2)

       (<= value1 value2)

       (= value1 value2)

       (== value1 value2)

       (<> value1 value2)

       (>= value1 value2)

       (> value1 value2)

 

Arguments


value1 The first value to be compared
value2 The second value to be compared.

 

When To Use

Use the relational operators when comparisons are essential to the success of your program.

 

Example 1

Here are just a few sample relational operations using the a range of values.

 

    (setq x (+ 10 20))Returns   30

    (< x 15)Returns   true

    (<= x -1)Returns   false

    (= x 30.0)Returns   true

    (= x "30")Returns   false

    (setq x "Hello World")Returns   "Hello World"

    (<> x "Hello World")Returns   false

    (= x[6] #\W)Returns   true

    (setq y #(#\H #\W #\O)Returns   #(#\H #\W #\O)

    (= x[6] y[1])Returns   true

 

Notes & Hints

Use the relational operators to return the results of value comparisons.

Comparison Operators LT LE EQ NE GE GT

The Comparison Operators LT LE EQ NE GE GT support the basic comparison operation (compare), as well as the basic comparison operations of less than (compareGT), less than or equal (compareGE), not equal (compareNE), equal (compareEQ), greater than or equal (compareGE), and greater than (compareGT). Each comparison operator is treated as a function call (as is everything else in Lisp). Each comparison operator must have two arguments.

The comparison operator (compare) returns -1 if arg1 is less then arg2, returns 0 if arg1 is equal to arg2, and returns 1 if arg1 is greater then arg2. The less than (compareLT) operator returns true if arg1 is less than arg2. The less than or equal (compareLE) operator returns true if arg1 is less than or equal to arg2. The not equal (compareNE) operator returns true if arg1 is not equal to arg2. The equal (compareEQ) operator returns true if arg1 is equal to arg2. The greater than or equal (compareGE) operator returns true if arg1 is greater than or equal to arg2. The greater than (compareGT) operator returns true if arg1 is greater than arg2.

The comparison operators may optionally be prefixed with a strong typing indicator, which causes the appropriate memory to memory strongly typed comparison operators to be invoked. The values of the optional strong typing indicators t are as follows.

 

Type:       Function

 

Syntax examples

 

       (compare value1 value2)

       (compareCC value1 value2)

       (tcompareCC value1 value2)

 

Arguments


value1 The first value to be compared
value2 The second value to be compared.

 

When To Use

Use the comparison operators when comparisons are essential to the success of your program.

 

Example 1

Here are just a few sample comparison operations using the a range of values.

 

    (setq x (+ 10 20))Returns   30

    (icompareLT x 15)Returns   true

    (compareLE x -1)Returns   false

    (ncompareEQ x 30.0)Returns   true

    (compareEQ x "30")Returns   false

    (setq x "Hello World")Returns   "Hello World"

    (compareNE x "Hello World")Returns   false

    (ccompareEQ x[6] #\W)Returns   true

    (setq y #(#\H #\W #\O)Returns   #(#\H #\W #\O)

    (compareEQ x[6] y[1])Returns   true

 

Notes & Hints

Use the comparison operators to return the results of value comparisons.

lambda

Overview

The lambda special form creates a new Agent object and returns it to the caller.

Type:              Special From

Syntax:           (lambda(args...) faces:(var...) svars:(var...) vars:(var...) pvars:(var...) cvars:(var...) regs:(var...) exp...)

The lambda special form creates a new executable Agent object. When called, the Agent extends its environment to include the specified argument variables {arg}, the arguments are received and bound to the proper variables {arg}, the expressions {exp} are evaluated from left to right, and the value of the final expression is returned. The new Agent object may be either a root agent or it will be a child agent of any agent within which it is declared. Child lambda agents are always registered in the pvars:() of their parent agent. The new Agent may be called directly when the arguments specified in its argument list.

Operating alone, agents are of limited capability and value. Operating in communities, agents have immense value and capabilities. AIS Lisp allows individual agents to be formed together into large agent communities of complex architecture. Agents can work together as classes, methods, children, friends, orphans, macros, all in increasing layers of complexity. A community of agents brought together to accomplish a specific set of tasks AND which can be used as a mobile TOOL is called an agent library. The precise qualities which cause an agent community to evolve from a simple hodpodge into a useful library are qualitative. However useful agent libraries come in two distinctive flavors: Agent oriented Libraries (AOP), and Object Oriented Libraries (OOP). Agent oriented library tools present their users with a functional interface wherein data is passed to functional agent-objects which causes work to be performed. Object oriented library tools present their users with a data interface wherein messages are passed to data-objects which causes work to be performed. AIS Lisp allows agent libraries of either flavor to be created and mixed together in arbitrary layers of complexity.

An AIS Agent may be defined, with a definite list (fixed) or an indefinite list of arguments (variable). The ellipses at the end of the argument list indicate the function has indefinite arguments. At run time, the Agent's actual arguments are bound to the specified formal definite arguments respectively. An error is generated if there are too few arguments in the definite argument list. If the number of actual arguments exceed the number of definite arguments, and the function has been defined as having indefinite arguments, the excess arguments can only be accessed during via the argCount and argFetch functions at run time.

The keyword faces:(var...) declares the interfaces feature Structure of the Agent. The features are specified as lists, faces:((english true) (french false)), the listed feature is initialized to the value specified.

The keyword svars:(var...) declares the class variables of the Agent. The variables are specified as follows svars:(X Y...). If any one of the variables is specified as a list, vars:((X 0) Y), the listed variable is initialized to the constant value specified (The variable X is initialized to the constant 0). Unlike the setq or define special forms, the svars special form always evaluates the initialization value as a constant. A variable may be strongly typed if a type preceeds the variable, svars:((Number:X 0.0) String:Y). If no type is specified, the variable defaults to type Word.

The keyword vars:(var...) declares the temporary variables of the Agent. The variables are specified as follows vars:(X Y...). If any one of the variables is specified as a list, vars:((X 0) Y...), the listed variable is initialized to the constant value specified (The variable X is initialized to the constant 0). Unlike the setq or define special forms, the vars special form always evaluates the initialization value as a constant. A variable may be strongly typed if a type preceeds the variable, vars:((Number:X 0.0) String:Y). If no type is specified, the variable defaults to type Word.

The keyword pvars:(var...) declares the persistent variables of the Agent. The variables are specified as a list pvars:(X Y...). If any one of the variables is specified as a list, pvars:((X 0) Y...), the listed variable is initialized to the constant value specified (The variable X is initialized to the constant 0). Unlike the setq or define special forms, the pvars special form always evaluates the initialization value as a constant. A variable may be strongly typed if a type preceeds the variable, pvars:((Integer:X 0) Vector:Y). If no type is specified, the variable defaults to type Word.

The keyword cvars:(var...) declares the constant variables of the Agent. The variables are specified as a list cvars:(X Y...). If any one of the variables is specified as a list, pvars:((X 0) Y...), the listed variable is initialized to the constant value specified (The variable X is initialized to the constant 0). Unlike the setq or define special forms, the cvars special form always evaluates the initialization value as a constant. A variable may be strongly typed if a type preceeds the variable, cvars:((Boolean:X 0) Number:Y). If no type is specified, the variable defaults to type Word.

The keyword regs:(var...) declares the register variables of the Agent. The variables are specified as a list regs: (X Y...). If any one of the variables is specified as a list, regs:((X 0) Y...), the listed variable is initialized to the constant value specified (The variable X is initialized to the constant 0). Up to fifty register variables are allowed. Unlike the setq or define special forms, the regs special form always evaluates the initialization value as a constant. A variable may be strongly typed if a type preceeds the variable, regs:((Integer:X 0) CharPointer:Y). If no type is specified, the variable defaults to type Integer.

The body of the Agent is a sequence of Lisp expressions {exp}. At run time, each of the expressions is evaluated, in the extended environment, from left to right. The Agent returns the value of the final expression in the sequence.

When To Use

Use this special form when a new Agent must be declared in Lisp.

Arguments


(arg...) Zero or more argument variable declarations.
faces:(var...) (Optional)The agent interfaces declarations.
svars:(var...) (Optional)The agent class variable declarations.
pvars:(var...) (Optional)The agent persistant variable declarations.
cvars:(var...) (Optional)The agent constant variable declarations.
vars:(var...) (Optional)The agent temporary variable declarations.
regs:(var...) (Optional)The agent register variable declarations.
expression... (Mandatory)One or more Lisp expressions defining the body of the Agent.
Returns The new Agent object.

Example 1

Here the Agent expressed as a lambda expressed is immediately invoked with the argument 4.

((lambda(X) (+ X X)) 4)     ==>     8

Note: The lambda special form returns a new Agent object, which is immediately executed. This newly minted agent is passed a numeric argument and a numeric result is returned.

Example 2

Here a slightly more complex Agent is assigned to a global variable.

(define sumNums (lambda(X ...)

          vars:(Z)

          (setq Z X)

          (loop for i from 1 to (-1+ (argCount)) do (setq Z (+ Z (argFetch i))))

          Z ))

(sumNums 4 5 71)     ==>     80

Note: The lambda special form returns a new Agent object, which assigned to the specified global variable name. This newly minted agent is passed a series of numeric arguments and a numeric result is returned.

defclass

Overview

The defclass special form creates a new Class Agent and assigns it to the specified global variable name.

Type:              Special From

Syntax:           (defclass libarary:parent:name(args...) svars:(var...) faces:(var...) vars:(var...) pvars:(var...) cvars:(var...) regs:(var...) exp...)

The new class Agent creates a new class of object and may be either a root class or it may inherit from an existing class or class library. The class Agent may be called directly when the class itself is to be initialized. The class Agent may be specified as the argument to the new function when an object of the specified class is to be created. An object of the specified class contains the variables as declared in the svars:() plus any variables which may have been inherited from the parent and/or library classes. The keyword self is used in the class argument lists to denote the current instance of the class object. Whenever the keyword self is declared as the first argument to any method of the class, the Sv register is automatically used for addressing. Whenever the variables declared in the svars:() are referenced on their own, it is assumed that the intended reference is self.

The class Agent may contain a new method which will be invoked whenever the class agent is specified as the argument to the new function. The new function is invoked when an object of the specified class is to be created. The new method must declare the self variable as its first argument and should always return self as its result.

After compilation, the class Agent will contain a methods list in its Interfaces section named classMethods. Also, the class Agent will contain a class names list in its Interfaces section named classNames. Plus the parent and library properties in the Interfaces section will be set appropriately, and class property in the Interfaces section will be set true. When the new function is invoked to create an object of the specified class, the new object is linked to the class methods list. Through this manner, the methods list of each class can be separate and distinct while still benefiting from inheritance.

Child classes, which inherit from other classes, will always be friend agents of their parent class agent. After compilation, child class agents are linked to their parent classes and to their library classes via the classNames, parent, and library properties of the class agent Interfaces sections. Normally, friend agents of a class agent are NOT added to the class names list.

Operating alone, agents are of limited capability and value. Operating in communities, agents have immense value and capabilities. AIS Lisp allows individual agents to be formed together into large agent communities of complex architecture. Agents can work together as classes, methods, children, friends, orphans, all in increasing layers of complexity. A community of agents brought together to accomplish a specific set of tasks AND which can be used as a mobile TOOL is called an agent library. The precise qualities which cause an agent community to evolve from a simple hodpodge into a useful library are qualitative. However useful agent libraries come in two distinctive flavors: Agent oriented Libraries (AOP), and Object Oriented Libraries (OOP). Agent oriented library tools present their users with a functional interface wherein data is passed to functional agent-objects which causes work to be performed. Object oriented library tools present their users with a data interface wherein messages are passed to data-objects which causes work to be performed. AIS Lisp allows agent libraries of either flavor to be created and mixed together in arbitrary layers of complexity.

WARNING: All class names, within a single class library, must be unique!

Note: See also the lambda special form for additional information on creating Agents objects.

When To Use

Use this special form when a new class Agent must be declared in Lisp.

Arguments


library (Optional)The symbolic name of the class library from which the new class is to inherit (must be a Symbol).
parent (Optional)The symbolic name of the immediate parent class from which the new class is to inherit (must be a Symbol).
name The symbolic name for the new class (must be a Symbol).
(arg...) Zero or more argument variable declarations.
svars:(var...) (Mandatory)The class variable declarations.
faces:(var...) (Optional)The class interfaces declarations.
pvars:(var...) (Optional)The class persistant variable declarations.
cvars:(var...) (Optional)The class constant variable declarations.
vars:(var...) (Optional)The class temporary variable declarations.
regs:(var...) (Optional)The class register variable declarations.
expression... (Mandatory)One or more Lisp expressions defining the body of the class Agent.
Returns The new Class Agent.

Example 1

Creating and initializing a new class of object.

(defclass employee()

          svars:(String:Name (Number:Salary 0.0))

          (defun new(self String:name Number:salary)

              (setq Name name)

              (setq Salary salary)

              self) ;; end of new method

          true) ;; end of employee class

(setq x (new employee "John Doe" 24000.0))

x.Name     ==>     "John Doe"

x.Salary     ==>     24000.0

Note: The new function creates a new copy of the class object, containing all of the variables as declared in the svars:(). This newly minted copy of the class object is passed to the new method as the argument self. The Sv register is automatically set to address the self argument so any reference to the svars:() variables will effect the self object.

One of the most important events occurs at the end of an class's life span, just before the class agent is destroyed. When an class agent object is no longer referenced, the garbage collector may choose to destroy the agent. Before final destruction takes place, the class agent will be sent a doomed message.

Each Agent's EvalWhenDoomed property is initially set to false. Normally, garbage collecting an Agent, causes nothing to happen (other than the destruction of the agent); however, if the class Agent's EvalWhenDoomed property is set to true, then the doomed agent is evaluated by the garbage collector BEFORE final destruction.

For instance, the following class opens a log file and performs operations on the open log file during the life span of the class. When the class agent is destroyed, we do not wish the log file to be left open. The class agent has the task of responding to the doomed event and closing the file before final destruction.

Example 2

This example shows how the class agent can open a log file at class initialization time, keep it open during the life of the class, and close the log file before the class is destroyed.

(defclass myClass(fileName)

          svars:(String:WidgetName Integer:Widget)

          pvars:(logFileHandle)

          (defun closeLog() (setq logFileHandle (fileClose logFileHandle)))

          (defun writeLog(record) (fileWrite logFileHandle record))

          ClassInitialization::

          (setq logFileHandle (fileOpen fileName))

          (setq closeLog.EvalWhenDoomed true)

          logFileHandle)

defun

Overview

The defun special form creates a new Agent and assigns it to the specified global variable name.

Type:              Special From

Syntax:           (defun name(args...) faces:(var...) vars:(var...) pvars:(var...) cvars:(var...) regs:(var...) exp...)

The defun special form creates a new executable object which is assigned to the specified global name. The new Agent object may be either a root agent or it will be a child agent of any agent within which it is declared. Child defun agents are always registered in the pvars:() of their parent agent. The new Agent may be called directly when the arguments specified in its argument list.

Operating alone, agents are of limited capability and value. Operating in communities, agents have immense value and capabilities. AIS Lisp allows individual agents to be formed together into large agent communities of complex architecture. Agents can work together as classes, methods, children, friends, orphans, all in increasing layers of complexity. A community of agents brought together to accomplish a specific set of tasks AND which can be used as a mobile TOOL is called an agent library. The precise qualities which cause an agent community to evolve from a simple hodpodge into a useful library are qualitative. However useful agent libraries come in two distinctive flavors: Agent oriented Libraries (AOP), and Object Oriented Libraries (OOP). Agent oriented library tools present their users with a functional interface wherein data is passed to functional agent-objects which causes work to be performed. Object oriented library tools present their users with a data interface wherein messages are passed to data-objects which causes work to be performed. AIS Lisp allows agent libraries of either flavor to be created and mixed together in arbitrary layers of complexity.

WARNING: All child agent names, within a single agent library, must be unique!

Note: See also the lambda special form for additional information on creating Agents objects.

When To Use

Use this special form when a new Agent must be declared in Lisp.

Arguments


name The symbolic name for the new Agent (must be a Symbol).
(arg...) Zero or more argument variable declarations.
faces:(var...) (Optional)The agent interfaces declarations.
pvars:(var...) (Optional)The agent persistant variable declarations.
cvars:(var...) (Optional)The agent constant variable declarations.
vars:(var...) (Optional)The agent temporary variable declarations.
regs:(var...) (Optional)The agent register variable declarations.
expression... (Mandatory)One or more Lisp expressions defining the body of the Agent.
Returns The new Agent object.

Example 1

This example shows that the defun special form is equivalent to a version of the define special form. This first form:

(defun times(X)

          vars:((Z 5))

          pvars:((Y 10))

          (* X Y Z))

is equivalent to this second form:

(define times

          (lambda(X)

              vars:((Z 5))

              pvars:((Y 10))

              (* X Y Z)))

(times 2)     ==>     100

Note: The defun special form creates a new Agent object, containing all of the variables as declared in the pvars:() and vars:(). This newly minted agent is passed a numeric argument and a numeric result is returned.

One of the most important events occurs at the end of an agent's life span, just before the agent is destroyed. When an agent object is no longer referenced, the garbage collector may choose to destroy the agent. Before final destruction takes place, the agent will be sent a doomed message.

Each Agent's EvalWhenDoomed property is initially set to false. Normally, garbage collecting an Agent, causes nothing to happen (other than the destruction of the agent); however, if the Agent's EvalWhenDoomed property is set to true, then the doomed agent is evaluated by the garbage collector BEFORE final destruction.

For instance, the following agent library opens a log file and performs operations on the open log file during the life span of the library. When the agent is destroyed, we do not wish the log file to be left open. The agent has the task of responding to the doomed event and closing the file before final destruction.

Example 2

This example shows how an agent library can open a log file at initialization time, keep it open during the life of the agent library, and close the log file before the library is destroyed.

(defun myAgent(fileName)

          pvars:(String:WidgetName Integer:Widget)

          pvars:(logFileHandle)

          (defun closeLog() (setq logFileHandle (fileClose logFileHandle)))

          (defun writeLog(record) (fileWrite logFileHandle record))

          Initialization::

          (setq logFileHandle (fileOpen fileName))

          (setq closeLog.EvalWhenDoomed true)

          logFileHandle)

Example 3

This example shows how an agent library can create and share a user-defined Structure template containing strongly-typed variable declarations.

(defun myAgent(fileName)

          pvars:((Structure:Thing #{decl| String:Name Number:Salary Integer:ID}))

          vars:(Structure:{Thing}x)

          (defun raise(Structure:{Thing}y Number:amount) (+= y.Salary amount))

          Initialization::

          (setq x (new Thing))

          (raise x 20000.00)

          x)

defchild

Overview

The defchild special form creates a new child Agent and assigns it to the specified parent agent. The new child Agent object is always assigned to the pvars:() of the specified parent Agent. The defchild special form always returns the newly created child Agent object.

Type:              Special From

Syntax:           (defchild parent:name(args...) faces:(var...) vars:(var...) pvars:(var...) cvars:(var...) regs:(var...) exp...)

                        (defchild parent name(args...) faces:(var...) vars:(var...) pvars:(var...) cvars:(var...) regs:(var...) exp...)

                        (defchild parent.member name(args...) faces:(var...) vars:(var...) pvars:(var...) cvars:(var...) regs:(var...) exp...)

The defchild special form creates a new executable object which is assigned to the specified parent name. The new Agent object will be a child agent of the parent agent to which it is declared. Child agents are always registered in the pvars:() of their parent agent, and child agents always have their pvars:() as the pvars:() of their parent. Child agents always have their cvars:() as the cvars:() of their parent. The new Agent may be called directly with the arguments specified in its argument list.

Operating alone, agents are of limited capability and value. Operating in communities, agents have immense value and capabilities. AIS Lisp allows individual agents to be formed together into large agent communities of complex architecture. Agents can work together as classes, methods, children, friends, orphans, all in increasing layers of complexity. A community of agents brought together to accomplish a specific set of tasks AND which can be used as a mobile TOOL is called an agent library. The precise qualities which cause an agent community to evolve from a simple hodpodge into a useful library are qualitative. However useful agent libraries come in two distinctive flavors: Agent oriented Libraries (AOP), and Object Oriented Libraries (OOP). Agent oriented library tools present their users with a functional interface wherein data is passed to functional agent-objects which causes work to be performed. Object oriented library tools present their users with a data interface wherein messages are passed to data-objects which causes work to be performed. AIS Lisp allows agent libraries of either flavor to be created and mixed together in arbitrary layers of complexity.

WARNING: All child agent names, within a single agent library, must be unique!

Note: See also the lambda special form for additional information on creating Agents objects.

When To Use

Use this special form when a new child Agent must be declared in Lisp.

Arguments


parent The parent agent of the new child Agent (must be a Symbol or an Agent).
name The symbolic name for the new Agent (must be a Symbol).
(arg...) Zero or more argument variable declarations.
faces:(var...) (Optional)The agent interfaces declarations.
pvars:(var...) (Optional)The agent persistant variable declarations.
cvars:(var...) (Optional)The agent constant variable declarations.
vars:(var...) (Optional)The agent temporary variable declarations.
regs:(var...) (Optional)The agent register variable declarations.
expression... (Mandatory)One or more Lisp expressions defining the body of the Agent.
Returns The new Agent object.

Example 1

This example shows how child agents can be defined in separate source files from their parent. For instance, the following two separate forms

(defun foo(x) pvars:(y) (setq y x))

(defchild foo:sum(x) (+ x y))

are equivalent to the following single form

(defun foo(x)

          pvars:(y)

              (defun sum(x) (+ x y))

              (setq y x))

(foo 10)     ==>     10

(foo.sum 3)     ==>     13

Note: Note: A child Agent DOES share the same pvars:() and cvars:() variables as its parent Agent. A friend Agent has a different pvars:() structure from its parent Agent, but the cvars:() structure of a friend Agent is the pvars:() structure of its parent Agent.

define

Overview

The defined special form assigns a value to the specified variable name at compile time. The specified name will either be bound to a global symbol or to the pvars:() of the parent agent depending on whether the define special form is invoked outside of or inside another agent. The major difference between the define nd the setq special forms is that the form makes its assignment once at compile time.

Type:              Special From

Syntax:           (define name expression)

                        (define (name args...) faces:(var...) vars:(var...) pvars:(var...) cvars:(var...) regs:(var...) exp...)

                        (define macro: (name arg...) faces:(var?) vars:(var...) pvars:(var...) cvars:(var...) regs:(var...) exp...)

                        (define vm: (name arg...) faces:(var?) vars:(var...) pvars:(var...) cvars:(var...) regs:(var...) exp...)

The (define (name args...) special form provides support for a Scheme-like version of defun. Review the defun special form in this document. We will provide further documentation there.

The (define macro: (name args...) special form provides support for a Scheme-like version of defmacro. Review the defmacro special form in this document. We will provide further documentation there.

The (define vm: (name args...) special form provides support for a Scheme-like version of defvm. Review the defvm special form in this document. We will provide further documentation there.

When To Use

Use this special form when a variable must be initialized in Lisp.

Arguments


name The symbolic name for the variable to be initialized at compile time (must be a Symbol).
expression (Mandatory)One Lisp expression to be assigned to the specified variable name at compile time.
Returns The value of the assigned expression.

Example 1

This example shows how variables may be initialized in Lisp.

(define y 33)

(defun foo(x) (define y 22) (+= y x))

y     ==>     33

foo.y     ==>     22

(foo 10)     ==>     32

foo.y     ==>     32

(foo 10)     ==>     42

foo.y     ==>     42

Note: Note: The define special form assigns to global variables when it is invoked with global scope. However, if defined within an agent, the define special form assigns to the pvars:() of the parent agent. Note that the define special form assigns only once a compile time not every time the agent is executed.

defmacro

Overview

The defmacro special form creates a new Macro Agent object, assigns it to the specified variable name and returns the newly created Macro Agent object. The new Macro agent will be invoked by the compile function during the macro substitution phase of compilation (see the compile, and morph functions).

Type:              Special From

Syntax:           (defmacro name(args...) faces:(var...) vars:(var...) pvars:(var...) cvars:(var...) regs:(var...) exp...)

                        (defmacro parent:name(args...) faces:(var...) vars:(var...) pvars:(var...) cvars:(var...) regs:(var...) exp...)

                        (defmacro parent name(args...) faces:(var...) vars:(var...) pvars:(var...) cvars:(var...) regs:(var...) exp...)

                        (defmacro parent.member name(args...) faces:(var...) vars:(var...) pvars:(var...) cvars:(var...) regs:(var...) exp...)

The defmacro special form creates a new executable object which is assigned to the specified global name. The new macro agent object will always be registered in the global name space, and may be invoked directly in any Lisp expression. Macro agents can be used to enhance any class or agent library. It is an AIS Lisp traditional to name all macros, in a library, after the global name of the class or agent library with an extending dash "_" symbol. For instance, if our class library has the name ourClassLibrary, then traditionally the enhancing macros for our class library would be named ourClassLibrary_Macro1, ourClassLibrary_Macro2, etc.

Operating alone, agents are of limited capability and value. Operating in communities, agents have immense value and capabilities. AIS Lisp allows individual agents to be formed together into large agent communities of complex architecture. Agents can work together as classes, methods, children, friends, orphans, macros, all in increasing layers of complexity. A community of agents brought together to accomplish a specific set of tasks AND which can be used as a mobile TOOL is called an agent library. The precise qualities which cause an agent community to evolve from a simple hodpodge into a useful library are qualitative. However useful agent libraries come in two distinctive flavors: Agent oriented Libraries (AOP), and Object Oriented Libraries (OOP). Agent oriented library tools present their users with a functional interface wherein data is passed to functional agent-objects which causes work to be performed. Object oriented library tools present their users with a data interface wherein messages are passed to data-objects which causes work to be performed. AIS Lisp allows agent libraries of either flavor to be created and mixed together in arbitrary layers of complexity.

WARNING: All macro agent names must be unique within the global name space!

Note: See also the lambda special form for additional information on creating Agents objects.

When To Use

Use this special form when creating a new in-line macro, which expands its arguments, rather than invoking a function call.

Arguments


parent The parent agent of the new macro Agent (must be a Symbol or an Agent).
name The symbolic name for the new Macro Agent (must be a Symbol).
(arg...) Zero or more argument variable declarations.
faces:(var...) (Optional)The agent interfaces declarations.
pvars:(var...) (Optional)The agent persistant variable declarations.
cvars:(var...) (Optional)The agent constant variable declarations.
vars:(var...) (Optional)The agent temporary variable declarations.
regs:(var...) (Optional)The agent register variable declarations.
expression... (Mandatory)One or more Lisp expressions defining the body of the Agent.
Returns The new list for additional compilation.

Example 1

In this example, we demonstrate how macros can be used to reduce complex expressions to simpler forms at compile time. The plus macro is defined as follows:

(defmacro plus(x y)

          (if (or (isSymbol x) (isSymbol y))

              (list |+|: x y)

              (+ x y)))

The following form:

(plus 10 20)

is replaced, in-line, with the number

30

but this more complex form:

(plus x 34)

is replaced, in-line, with this form

(+ x 34)

Note: Note: In the language of compilers, the plus macro performs constant folding.

Example 2

This square macro expands its arguments in-line rather than calling a function.

(defmacro square(x) (list |*|: x x))

By invoking the macro below

(square 23)

we generate in-line code as follows:

(* 23 23)

Note: Note: The defmacro special form allows complete control of the macro substitution process during compilation. The macro agent may be as complex as required, including macro agents which are complex agent libraries.

One of the most important features of AIS Lisp macros is the complete control offered over the macro substitution process. In cases where very simple manipulation of the macro substitution process is required, the defmacro special form can be used with the macroReplace function to provide simple argument substitution similar to the macros in the C language.

Example 3

In this example, we demonstrate how Lisp macros can be used, together with the macroReplace function, to provide simple argument substitution similar to the macros in the C language. The plus macro can also be defined as follows:

(defmacro plus(%1 %2) (macroReplace %1 %2 '(+ %1 %2)))

The following form:

(plus (mod 2 3) 4)

is replaced, in-line, with this form:

(+ (mod 2 3) 4)

Note: Note: The macroReplace function may take any number of arguments. Each argument must be named %nn (where nn is a sequential argument number). The last argument must be a source string of any size (either enclosed in braces or double quotes). Each instance of an argument notation %nn in the source string will be replaced, in the source string, by the appropriate argument. The final argument will be converted into a List and returned as the final form for compilation.

defmethod

Overview

The defmethod macro creates a new method Agent for the specified Class Agent and adds it to the classMethods in the Interfaces section of the specified class agent.

Type:              Special From

Syntax:           (defmethod library:class:msgName(self args...) faces:(var...) vars:(var...) pvars:(var...) cvars:(var...) regs:(var...) exp...)

                        (defmethod typeName:msgName(self args...) faces:(var...) vars:(var...) pvars:(var...) cvars:(var...) regs:(var...) exp...)

If a typeName is specified, the defmethod special form constructs an Agent with at least one argument (which by convention is named self). The first argument, declared for the new method Agent, must be of the specified type typeName. The new method Agent is added to the Methods Structure of the specified type typeName. After adding the Agent to the Methods Structure of the specified type, the type will respond to the message named msgName by invoking the new methods Agent. The defmethod and defstruct special forms support the development of user defined types in AIS Lisp (for those applications where an object oriented type-paradigm is warranted).

If a class is specified, the new method Agent adds a new function or capability to the specified agent class library and may be a root method or may override an existing method of the class library. The method Agent may be called directly or it may be invoked by sending a message to any object instance of the specified class. The method Agent must declare self as its first argument followed by any number of additional arguments. Any object of the specified class contains the variables as declared in the class svars:() which always includes all additional svars:() variables inherited from the parent and library classes. The keyword self is used in the method argument lists to denote the current instance of the class object. Whenever the keyword self is declared as the first argument to any method of the class, the Sv register is automatically used for addressing. Whenever the variables declared in the svars:() are referenced on their own, it is assumed that the intended reference is self.

The specified class Agent will contain a methods list in its Interfaces section named classMethods After compilation, the new method Agent will be added to the methods list in the specified class agent. When the new function is invoked to create an object of the specified class, the new object is linked to the class methods list. Through this manner, a message sent to the object will invoke the corresponding method agent.

The method Agent always shares the svars:() pvars:() and cvars:() variables of the specified class agent. The new method agent is always a child agent of the class agent. The only difference between a simple child agent and a method agent is the method agent is added to the classMethods Structure in the Interfaces section of the class agent. Normally child, friend, and orphan agents are NOT added to the methods list of the class agent. Declare as methods only those functions which are to be publicly available via messages to objects of the specified class.

WARNING: All method agent names, within a single class agent, must be unique!

Note: See also the lambda special form for additional information on creating Agents objects.

When To Use

Use this macro when a class Agent must be extended with new functionality.

Arguments


library (Optional)The symbolic name of the class library to which the new method is to belong (must be a Symbol).
class or typeName The symbolic name of the agent class or type to which the new method is to belong (must be a Symbol).
msgName The symbolic name of the new method (must be a Symbol).
(self arg...) The mandatory self argument plus zero or more argument variable declarations.
faces:(var...) (Optional)The method agent interfaces declarations.
pvars:(var...) (Optional)The class agent persistant variable declarations.
cvars:(var...) (Optional)The class agent constant variable declarations.
vars:(var...) (Optional)The method agent temporary variable declarations.
regs:(var...) (Optional)The method agent register variable declarations.
expression... (Mandatory)One or more Lisp expressions defining the body of the method Agent.
Returns The programmer defined results of the method invocation.

Example 1

Creating and enhancing a new class of object with a new method function.

(defclass employee()

          svars:((String:Name "John Doe") (Number:Salary 0.0))

          true) ;; end of employee class

(defmethod employee:raise(self Number:amount)

          (+= Salary amount)

          Salary) ;; end of raise method

(setq x (new employee))

(raise:x 22000)     ==>     22000

Note: The new function creates a new object of the class, containing all of the variables as declared in the svars:(). In other words, self is an object containing members self.Name and self.Salary (see the svars:() declarations in the class agent). This newly minted copy of the class object is sent the "raise" message which invokes the raise method agent. In the raise method, the reference to Salary is assumed to be equivalent to a reference to self.Salary. The Sv register is automatically set to address the self argument. Therefore all references to the svars:() variables effect the self object.

One of the most important properties of class library construction is inheritance between class agents. Through inheritance a newly declared class may automatically obtain many of the properties of its parent and library class agents. For instance, the following class declarations show how properties of a parent class can be inherited by a child class.

Example 2

This example shows how the manager class agent inherits the properties of its parent class.

(defclass employee() svars:((String:Name "John Doe") (Number:Salary 0.0)) true)

(defmethod employee:raise(self Number:amount) (+= Salary amount) Salary)

(defclass employee:manager() svars:((String:Dept "Sales Division")) true)

(setq x (new employee.manager))

(raise:x 22000)     ==>     22000

Note: The new function creates a new object of the class "manager" (from the employee class library), containing all of the variables as declared in the svars:() of the manager class and all those variables svars:() variables declared in the parent class employee. In other words, self is an object containing members self.Name, self.Salary, and self.Dept (see the svars:() declarations in both employee and manager class agents). This newly minted copy of the manager object is sent the "raise" message which invokes the raise method agent. The raise method does not have to be defined again because the manager class inherits it from the employee class. In the raise method, the reference to Salary is assumed to be equivalent to a reference to self.Salary. The Sv register is automatically set to address the self argument. Therefore all references to the svars:() variables effect the self object.

Example 3

This example shows how the manager class agent may override an inherited properties of its parent class.

(defclass employee() svars:((String:Name "John Doe") (Number:Salary 0.0)) true)

(defmethod employee:raise(self Number:amount) (+= Salary amount) Salary)

(defclass employee:manager() svars:((String:Dept "Sales Division")) true)

(defmethod employee:manager:raise(self Number:amount) (+= Salary (* 1.2 amount)) Salary)

(setq x (new employee.manager))

(raise:x 20000)     ==>     24000

Note: The new function creates a new object of the class "manager" (from the employee class library), containing all of the variables as declared in the svars:() of the manager class and all those variables svars:() variables declared in the parent class employee. In other words, self is an object containing members self.Name, self.Salary, and self.Dept (see the svars:() declarations in both employee and manager class agents). This newly minted copy of the manager object is sent the "raise" message which invokes the manager's raise method agent. The raise method declared for the manager class overrides the raise method inherited from the parent employee class. The raise method does not have to be defined again because the manager class inherits it from the employee class. In the raise method, the reference to Salary is assumed to be equivalent to a reference to self.Salary. The Sv register is automatically set to address the self argument. Therefore all references to the svars:() variables effect the self object.

defriend

Overview

The defriend special form creates a new friend Agent and assigns it to the specified parent agent. The new friend Agent object is always assigned to the pvars:() of the specified parent Agent. The defriend special form always returns the newly created friend Agent object.

Type:              Special From

Syntax:           (defriend parent:name(args...) faces:(var...) vars:(var...) pvars:(var...) cvars:(var...) regs:(var...) exp...)

                        (defriend parent name(args...) faces:(var...) vars:(var...) pvars:(var...) cvars:(var...) regs:(var...) exp...)

                        (defriend parent.member name(args...) faces:(var...) vars:(var...) pvars:(var...) cvars:(var...) regs:(var...) exp...)

The defriend special form creates a new executable object which is assigned to the specified parent name. The new Agent object will be a friend agent of the parent agent to which it is declared. Friend agents are always registered in the pvars:() of their parent agent, and friend agents always have their pvars:() new an separate from the pvars:() of their parent. Friend agents always have their cvars:() shared as the pvars:() of their parent. Friend agents cannot see the cvars:() of their parent, and parents cannot see the pvars:() of their friend agents. The new Agent may be called directly with the arguments specified in its argument list.

Operating alone, agents are of limited capability and value. Operating in communities, agents have immense value and capabilities. AIS Lisp allows individual agents to be formed together into large agent communities of complex architecture. Agents can work together as classes, methods, children, friends, orphans, all in increasing layers of complexity. A community of agents brought together to accomplish a specific set of tasks AND which can be used as a mobile TOOL is called an agent library. The precise qualities which cause an agent community to evolve from a simple hodpodge into a useful library are qualitative. However useful agent libraries come in two distinctive flavors: Agent oriented Libraries (AOP), and Object Oriented Libraries (OOP). Agent oriented library tools present their users with a functional interface wherein data is passed to functional agent-objects which causes work to be performed. Object oriented library tools present their users with a data interface wherein messages are passed to data-objects which causes work to be performed. AIS Lisp allows agent libraries of either flavor to be created and mixed together in arbitrary layers of complexity.

WARNING: All friend agent names, within a single agent library, must be unique!

Note: See also the lambda special form for additional information on creating Agents objects.

When To Use

Use this special form when a new friend Agent must be declared in Lisp.

Arguments


parent The parent agent of the new friend Agent (must be a Symbol or an Agent).
name The symbolic name for the new Agent (must be a Symbol).
(arg...) Zero or more argument variable declarations.
faces:(var...) (Optional)The agent interfaces declarations.
pvars:(var...) (Optional)The agent persistant variable declarations.
cvars:(var...) (Optional)The agent constant variable declarations.
vars:(var...) (Optional)The agent temporary variable declarations.
regs:(var...) (Optional)The agent register variable declarations.
expression... (Mandatory)One or more Lisp expressions defining the body of the Agent.
Returns The new Agent object.

Example 1

This example shows how friend agents can be defined in separate source files from their parent. For instance, the following two separate forms

(defun foo(x) pvars:(y) (setq y x))

(defriend foo:sum(x) (+ x y))

(foo 10)     ==>     10

(foo.sum 3)     ==>     13

foo.Pv.y     ==>     10

foo.sum.Cv.y     ==>     10

Note: Note: A friend Agent does not share the same pvars:() variables with its parent; however, the cvars:() structure of a friend Agent is the pvars:() structure of its parent Agent.

deforphan

Overview

The deforphan special form creates a new orphan Agent and assigns it to the specified parent agent. The new orphan Agent object is always assigned to the pvars:() of the specified parent Agent. The deforphan special form always returns the newly created orphan Agent object.

Type:              Special From

Syntax:           (deforphan parent:name(args...) faces:(var...) vars:(var...) pvars:(var...) cvars:(var...) regs:(var...) exp...)

                        (deforphan parent name(args...) faces:(var...) vars:(var...) pvars:(var...) cvars:(var...) regs:(var...) exp...)

                        (deforphan parent.member name(args...) faces:(var...) vars:(var...) pvars:(var...) cvars:(var...) regs:(var...) exp...)

The deforphan special form creates a new executable object which is assigned to the specified parent name. The new Agent object will be an orphan agent of the parent agent to which it is declared. Orphan agents are always registered in the pvars:() of their parent agent, and Orphan agents always have their pvars:() new an separate from the pvars:() of their parent. Orphan agents always have their cvars:() new an separate from the cvars:() of their parent. Orphan agents cannot see the pvars:() of their parent, and orphan agents cannot see the cvars:() of their parent. Orphan agents cannot see their parent. The new Agent may be called directly with the arguments specified in its argument list.

Operating alone, agents are of limited capability and value. Operating in communities, agents have immense value and capabilities. AIS Lisp allows individual agents to be formed together into large agent communities of complex architecture. Agents can work together as classes, methods, children, friends, orphans, all in increasing layers of complexity. A community of agents brought together to accomplish a specific set of tasks AND which can be used as a mobile TOOL is called an agent library. The precise qualities which cause an agent community to evolve from a simple hodpodge into a useful library are qualitative. However useful agent libraries come in two distinctive flavors: Agent oriented Libraries (AOP), and Object Oriented Libraries (OOP). Agent oriented library tools present their users with a functional interface wherein data is passed to functional agent-objects which causes work to be performed. Object oriented library tools present their users with a data interface wherein messages are passed to data-objects which causes work to be performed. AIS Lisp allows agent libraries of either flavor to be created and mixed together in arbitrary layers of complexity.

WARNING: All orphan agent names, within a single agent library, must be unique!

Note: See also the lambda special form for additional information on creating Agents objects.

When To Use

Use this special form when a new orphan Agent must be declared in Lisp.

Arguments


parent The parent agent of the new orphan Agent (must be a Symbol or an Agent).
name The symbolic name for the new Agent (must be a Symbol).
(arg...) Zero or more argument variable declarations.
faces:(var...) (Optional)The agent interfaces declarations.
pvars:(var...) (Optional)The agent persistant variable declarations.
cvars:(var...) (Optional)The agent constant variable declarations.
vars:(var...) (Optional)The agent temporary variable declarations.
regs:(var...) (Optional)The agent register variable declarations.
expression... (Mandatory)One or more Lisp expressions defining the body of the Agent.
Returns The new Agent object.

Example 1

This example shows how orphan agents can be defined in separate source files from their parent. For instance, the following two separate forms

(defun foo(x) pvars:(y) (setq y x))

(deforphan foo:sum(x) pvars:((y 20)) (+ x y))

(foo 10)     ==>     10

(foo.sum 3)     ==>     23

foo.Pv.y     ==>     10

foo.sum.Pv.y     ==>     20

Note: Note: An orphan Agent does not share the same pvars:() variables with its parent; and, an orphan Agent does not share the same cvars:() variables with its parent;

defstruct

Overview

The defstruct special form creates and initializes a new Structure type {newType} with the specified field names {fieldnames}. There may be one or more field names. The new Structure type created by defstruct can inherit from another Structure by specifying the include: keyword and the name of the parent object {parentName}.

The defstruct special form results in the following substitution:

(defineStructure newType: include: parentName fieldnames....)

The defstruct special form is a mechanism for adding user-defined Structure types to the Agent Information Server context. The defstruct special form brings the conventional object-oriented paradigm to the Agent Information Server tool set. The special form describes a template for the new Structure type. The object is not instantiated until the constructor function is invoked. The new Structure type can inherit field names (analogous to OOP properties or members) and methods by using the include: syntax.

 

Type:              Special From

Syntax:           (defstruct newType: fieldnames....)

                       (defstruct newType: include: parentName fieldnames....)

 

Arguments


newType The symbolic name for the new Structure type.
include: An optional keyword. If present, it must be followed by an existing Structure type.
parentName If the include: keyword is present, it must be followed by an existing Structure type name.
fieldName... One or more symbolic field name declarations.
Returns The new Structure type.

 

When To Use

Use the defstruct special form whenever the creation of additional Structure types is appropriate.

 

Example 1

Here we create a new Structure type to represent employees.

    (defstruct Employee: Name: Address: Salary:)

    (defmethod Employee:raise(self amount) (+= self.Salary amount))

    (setq self (new Employee: Name: "John Doe" Address: "Las Vegas, Nevada" Salary: $20000.00))

    (raise: self $3000.00)   Returns   $23000.00

defvm

Overview

The defvm macro creates an Agent Virtual Machine object, assigns it to the specified global variable name in the global environment, and returns the newly created Agent Virtual Machine object. The new Virtual Machine Agent object is assigned to the specified global variable name, and can be used to control the behavior of any other Agent to which it is assigned.

Every AIS Agent object must be assigned a virtual machine, which controls the behavior of the Agent object when it is invoked. Normally, the compile function assigns the drmVirtualMachine to each Agent object which it compiles. The drmVirtualMachine controls Agent object behavior using a Dynamically typed word Register Machine model, and contains both an emulation mode and a Just-In-Time compiler. The defvm macro allows the creation of additional Agent Virtual Machines. These additional virtual machines can be used to implement alternative machine models or to provide profiling and debugging information.

 

Type:              Special From

Syntax:           (defvm name(arg...) faces:(vars?) regs:(var...) vars:(var...) pvars:(var...) cvars:(var...) exp...)

 

Operating alone, agents are of limited capability and value. Operating in communities, agents have immense value and capabilities. AIS Lisp allows individual agents to be formed together into large agent communities of complex architecture. Agents can work together as classes, methods, children, friends, orphans, all in increasing layers of complexity. A community of agents brought together to accomplish a specific set of tasks AND which can be used as a mobile TOOL is called an agent library. The precise qualities which cause an agent community to evolve from a simple hodpodge into a useful library are qualitative. However useful agent libraries come in two distinctive flavors: Agent oriented Libraries (AOP), and Object Oriented Libraries (OOP). Agent oriented library tools present their users with a functional interface wherein data is passed to functional agent-objects which causes work to be performed. Object oriented library tools present their users with a data interface wherein messages are passed to data-objects which causes work to be performed. AIS Lisp allows agent libraries of either flavor to be created and mixed together in arbitrary layers of complexity.

WARNING: All orphan agent names, within a single agent library, must be unique!

Note: See also the lambda special form for additional information on creating Agents objects.

When To Use

Use this special form when a new virtual machine Agent must be declared in Lisp.

Arguments


name The symbolic name for the new virtual machine Agent (must be a Symbol).
(arg...) Zero or more argument variable declarations.
faces:(var...) (Optional)The agent interfaces declarations.
pvars:(var...) (Optional)The agent persistant variable declarations.
cvars:(var...) (Optional)The agent constant variable declarations.
vars:(var...) (Optional)The agent temporary variable declarations.
regs:(var...) (Optional)The agent register variable declarations.
expression... (Mandatory)One or more Lisp expressions defining the body of the Agent.
Returns The new Agent object.

 

When To Use

Use the defvm special form whenever the creation of additional Agent Virtual Machines is appropriate. Additional Agent Virtual Machines can be used to implement alternative machine models or to provide profiling and debugging information.

 

Example 1

Here we create an Agent Virtual Machine whose job is to keep a count of the number of times each of its client agents is invoked.

    (defvm countVM(...)
       regs:(n)
       vars:(client x result)
       pvars:(clientList)
       ;; Retrieve my client (who will always be the last argument)
       (setq client (argFetch (sub1 (argCount))))
       ;; Initialize my client list (if necessary)
       (if (= clientList #void) (setq new clientList (new Dictionary:)))
       ;; Initialize this client count history (only on the first invocation)
       (if (= clientList[client] #void)
           (begin
              (setq n 0)
              (setq x (copy client)) ;; Make a copy of my client
              (setq x.Vm drmVirtualMachine:) ;; The copy will run on the standard DRM
              (vmregSaveTail n x) ;; Use the tail of the client to keep its count
              (setq clientList[client] x)
              )) ; end if
       (setq x clientList[client])
       (vmregLoadTail x n) ;; Use the tail of the client to keep its count
       (++ n)
       (vmregSaveTail n x)
       (setq clientList[client] x)
       (vmapply -1 x result)) ;; Invoke the client passing the original arguments

 

Notes & Hints

The defvm macro must define an Agent Virtual Machine whose last argument is always the agent whose behavior is to be controlled.

and

The and special form evaluates each expression from left to right. As soon as any expression evaluates to False, the and special form will return False. If all expressions evaluate to True, the value True is returned. If no expressions are specified, the value True is returned.

 

Type:       Special Form

 

Syntax examples

 

       (and exp ...)

 

Arguments


exp ? Any number of expressions to be evaluated
Returns If All expressions evaluate to True, True is returned. If one expression evaluate to False, False is returned. If no expressions are specified, True is returned.

 

When To Use

[...under construction...]

 

Example 1

Here are but a few examples of the and special form.

 

    (and (= 12 12) (> 2 1))Returns   true

    (and (= 24 24) (< 1 1))Returns   false

    (and 1 2 3 4 5)Returns   false

    (and) Returns   true

 

Notes & Hints

[...under construction...]

argCount

The argCount special form is the only method to return the number of arguments that was passed to the current Agent. The current Agent has been defined with an indefinite number of arguments using the ellipsis syntax form. The number of arguments is only known at runtime.

 

Type:       Special Form

 

Syntax examples

 

       (argCount)

 

Arguments


Returns The number of arguments for the current Agent.

 

When To Use

The argCount special form is the only method to return the number of arguments that was passed to the current Agent. The current Agent has been defined with an indefinite number of arguments using the ellipsis syntax form. The number of arguments is only known at runtime.

 

Example 1

Here is an example of the argCount special form in use.

 

    (define SumNums

       (lambda (X ...) vars:(Z)

          (setq Z X)

          (loop for i from 1 until (argCount) do

             (setq Z (+ Z (argFetch i))))

          Z))

    (SumNums 4 5 71)   Returns   80

 

Notes & Hints

An Agent Information Server Agent may be defined, with a definite list (fixed) or an indefinite list of arguments (variable) The ellipses at the end of the argument list indicates the function has indefinite arguments. At run time, the Agent's arguments are bound to the specified definite arguments respectively. The Lisp compiler can detect and generate an error message when there are too few arguments in the definite argument list. If the number of arguments exceed the number of definite arguments, the excess arguments can only be accessed during runtime via the argCount and argFetch functions. (see the lambda special form).

argFetch

The argFetch special form is used to access arguments in Agents which have been sent an indefinite number of arguments using the ellipses syntax form. The number of arguments are only known at runtime.

 

Type:       Special Form

 

Syntax examples

 

       (argFetch index)

 

Arguments


index The index of the argument to be fetched.
Returns The value of the indexed argument.

 

When To Use

The argFetch special form is used to access arguments in Agents which have been sent an indefinite number of arguments using the ellipses syntax form. The number of arguments are only known at runtime.

 

Example 1

Here is an example of the argCount special form in use.

 

    (define SumNums

       (lambda (X ...) vars:(Z)

          (setq Z X)

          (loop for i from 1 until (argCount) do

             (setq Z (+ Z (argFetch i))))

          Z))

    (SumNums 4 5 71)   Returns   80

 

Notes & Hints

An Agent Information Server Agent may be defined, with a definite list (fixed) or an indefinite list of arguments (variable) The ellipses at the end of the argument list indicates the function has indefinite arguments. At run time, the Agent's arguments are bound to the specified definite arguments respectively. The Lisp compiler can detect and generate an error message when there are too few arguments in the definite argument list. If the number of arguments exceed the number of definite arguments, the excess arguments can only be accessed during runtime via the argCount and argFetch functions. (see the lambda special form).

begin

The begin Special Form evaluates a sequence of expressions, and returns the value of the last expression. If no expressions are specified, the empty list () is returned.

 

Type:       Special Form

 

Syntax examples

 

       (begin expression ...)

 

Arguments


expression ... Any number of expressions to be evaluated.
Returns The value of the last expression evaluated is returned.

 

When To Use

The begin Special Form marks the beginning of a group of expressions that logically form a compound expression.

 

Example 1

Here is an example of the begin special form in action.

 

    (define Y (begin (+ 1 2) (+ 3 4)))   Returns   7

 

Notes & Hints

[...under construction...]

case

The case Special Form selects one of a series of clauses to evaluate based upon the value of a selector expression. (similar to the switch statement in the C programming language). Each clause is a list (matchexp resultexp) which contains a match expression followed by a result expression. Each match expression is an atom, a list of atoms, or the keyword else.

First the selector clause (selectorClause) expression is evaluated, and the result value is compared with the match expression from each match clause (matchClause) until the comparison returns true or until a match with the keyword else is encountered. The selector value is compared to each match expression using the isMember function, if the (matchClause) is a list, and the isEqual function, if (matchClause) is not a list. If no selector matches, the case special form returns the value False. If a clause is selected, the expression in the clause is evaluated. If no match occurred, and the else keyword is present, the expression following the else keyword will be evaluated.

 

Type:       Special Form

 

Syntax examples

 

      (case selectorClause (matchClause) ? )

      (case selectorClause (matchClause) ? (elseClause))

 

Arguments


selectorClause An expression to be evaluated.
(matchClause)'s Any number of matchClauses can be present. Each match clause is a list (matchexp resultexp) which contains a match expression followed by a result expression. Each match expression is an atom, a list of atoms.
(elseClause) (Optional) If present there can only be one else clause. Each else clause is a list (else resultexp). The head of the list is the keyword else followed by a result expression.
Returns The selectorClause is compared to each matchClause. If the match clause is a list the comparison implements isMember function to determine if the selector matches an element in the list. If the match clause is not a list, the isEqual function will be used to determine if the selector clause matches the match clause. If no selector matches, the case special form returns the value False. If a clause is selected, the expression in the clause is evaluated. If no match occurred, and the else keyword is present, the expression following the else keyword will be evaluated.

 

When To Use

[...under construction...]

 

Example 1

    (case (* 2 3)

       ((2 3 5 7) 'PRIME)

       ((1 4 6 8 9) 'COMPOSITE))   Returns   'COMPOSITE

 

Example 2

    (case (+ 4 -2)

       (1 '(DO-THIS))

       (2 '(DO-THAT))

       (else '(DO-THE-OTHER)))   Returns   '(DO-THAT)

 

Example 3

    (case 2

       (1 (+ 8 9))

       (2 (begin (+ 1 2) (* 4 5)))

       (else (/ 5 6)))   Returns   20

 

Notes & Hints

[...under construction...]

compile

The compile function compiles the Agent Information Server generic parse tree (parseTree) argument (normally the output from lisp) and returns an Agent object. If the optional (anAgent) argument is passed, it becomes the target of the compilation and is returned; otherwise, a new Agent object is returned. If the optional true argument is passed, the compilation always inherits the persistent variables of the optional (anAgent) argument.

 

Type:       Function

 

Syntax examples

 

       (compile parseTree)

       (compile parseTree anAgent)

       (compile parseTree anAgent true)

 

Arguments


parseTree An Agent Information Server generic parse tree (normally output from lisp)
anAgent Optional Argument. If present, it specifies the target (Agent) of the compilation. If not present, a new Agent object is returned.
true Optional Argument. If present, the compilation will inherit the persistent variables of the {anAgent} argument.
Returns An executable Agent object.

 

When To Use

Use the compile function when producing an Agent from a parse tree is required. Normally, a two step process will compile Lisp source: lisp, followed by compile.

 

Example 1

We can create Agents from Lisp source by using the compile function.

 

    (compile (lisp "(lambda(x) (+ x x))")))   Returns   #<Agent 291>

 

Notes & Hints

We can create Agent objects by using the makeAgent function (without resorting to using compile). For instance, an Agent to execute the following Lisp code.

    (lambda (n) #void)

Can be created from the following Lisp code.

    (makeAgent

       Av: #{n: 0}

       Pv: #{__C0 10}

       Pc: #(pcd| 0))

The same result can be obtained from the following Lisp expression.

    (compile '(lambda (n) #void))

cond

The cond Special Form selects one of a series of clauses to evaluate based upon the value of their guard expressions. Each guard expression is a list (guardexp resultexp). The head of the list is a guardexp which is a test expression that results in a Boolean value and the resultexp is any Lisp expression. From left to right each guard expression, is evaluated. If the result is True, the result expression is evaluated and the cond Special Form terminates. If the result is False, the following guard expressions are evaluated until a true is encountered or until the keyword else is encountered. If no guard expression is True or no else is present, the cond Special Form returns the Boolean value False.

 

Type:       Special Form

 

Syntax examples

 

      (cond ((guardexp) resultexp) ?)

      (cond ((guardexp) resultexp) ? (else resultexp))

 

Arguments


guardexp An expression to be evaluated.
((guardexp) resultexp)'s Any number of ((guardexp) resultexp) clauses can be present. Each guardexp is a Lisp expression which, if it returns true, will cause its (resultexp) to be evaluated. Only the resultexp, paired with the first true guardexp, is evaluated. All remaining ((guardexp) resultexp) clauses are skipped. If no guardexp ever returns true, then the optional else clause is evaluated (if present).
(else resultExp) (Optional) If present there can only be one else clause. Each else clause is a list (else resultexp). The head of the list is the keyword else followed by a result expression.
Returns Each guardexp is evaluated. If no guardexp returns true, the cond special form returns the value False. If a guardexp return true, the resultexp in the clause is evaluated and the value of that resultexp is returned. If no guardexp returns true, and the else keyword is present, the expression following the else keyword will be evaluated.

 

When To Use

The cond Special Form behaves like a series of Lisp if - else special forms. Use the cond special form when the use of multiple if - else forms would make the program less readable.

 

Example 1

 

    (cond ((> 3 2) 'GREATER)

       ((< 3 2) 'LESS-THAN))   Returns   'GREATER

 

Example 2

 

    (cond ((> 3 3) 'GREATER)

       ((< 3 1) 'LESS-THAN)

       (else 'EQUAL))   Returns   'EQUAL

 

Example 3

 

    (cond ((> 3 3) 'GREATER)

       ((< 3 1) 'LESS-THAN)   Returns   false

 

Notes & Hints

[...under construction...]

eval

The eval Function evaluates the argument {exp} and returns the resulting value. When the input to eval is a List, invoking eval is equivalent to invoking compile, and eval. If the eval Function is passed a string as an argument, invoking eval is equivalent to invoking lisp, compile, and eval. If the eval Function is passed an agent as an argument, invoking eval is equivalent to invoking the agent with no arguments.

 

Type:       Function

 

Syntax examples

 

       (eval string)

       (eval list)

       (eval agent)

 

Arguments


string A string containing a Lisp language expression to be compiled and evaluated.
Returns Always returns the result of (eval (compile (lisp string))).

list A list containing a parse tree expression to be compiled and evaluated.
Returns Always returns the result of (eval (compile list)).

agent An agent to be invoked with no arguments.
Returns Always returns the result of (agent).

 

When To Use

Use the eval function whenever a lisp expression or an agent needs to be evaluated.

 

Example 1

Here follows an example of the eval function in action.

 

    (eval {(lambda() "Hello world")})   Returns   "Hello World"

 

Notes & Hints

The eval Function should only be passed agents of zero arguments.

goto

The goto special form allows Lisp Agents to transfer control to goto labels within an Agent. The goto label is a symbol that is suffixed with the :: character pair when it is defined, and with the : character when it is referenced in the goto expression.

 

Type:       Special Form

 

Syntax examples

 

       (goto label:)

 

       (goto register)

 

Arguments


label The label of the location where execution control is to be transferred.
Returns The program will start executing at the position specified by the label:: and the goto special form returns True.

register The name of a register containing the location where execution control is to be transferred.
Returns The program will start executing at the position specified by the label:: and the goto special form returns True.

 

When To Use

The goto special form is used to handle unconditional branches within an Agent.

 

Example 1

Here follow just a few examples of goto forms in action.

 

    (defun foo(X)

       (goto TWO:)

       ONE::

       (writeln "ONE " X)

       (goto EXIT:)

       TWO::

       (writeln "TWO" )

       (goto ONE:)

       EXIT::

       (writeln "foo EXIT" ))   Returns   #<Agent 2195>

The invocation of foo produces the following console output.

    (foo 1)   Returns   true

    console   ==>   TWO

    console   ==>   ONE 1

    console   ==>   foo EXIT

 

Notes & Hints

[...under construction...]

Conditional goto

The conditional goto gotoCCt special form allows Lisp Agents to conditionally branch to goto labels within an Agent. The expressions {exp1} and {exp2} are evaluated and {exp2} is compared with {exp1}. If the specified condition CC of the gotoCC conditional goto is true, then the program will start executing at the location specified by the (LabelName:). The conditional goto label is a symbol that is suffixed with the :: character pair when it is defined, and with the : character when it is referenced in the conditional goto expression. The values of the goto contitionals CC are as follows.

An optional strong typing indicator gotoCCt may be appended, which causes the generation of the appropriate memory to memory strongly typed comparison. The values of the optional strong typing indicators t are as follows.

 

Type:       Function

 

Syntax examples

 

       (gotoCC exp1 exp2 LabelName:)

       (gotoCCt exp1 exp2 LabelName:)

 

Arguments


exp1 The first expression to be compared.
exp2 The second expression to be compared.
LabelName The label of the location where execution control is to conditionally be transferred.
Returns The program will conditionally start executing at the position specified by the label:: and the conditional goto special form returns True.

 

When To Use

The conditional goto Special Form is used whenever it is necessary to test for a condition before branching to a location (label) in an Agent.

 

Example 1

Here follow just a few examples of conditional goto forms in action.

 

    (defun foo(X)

       (gotoGTi (* X 2) 0 TWO:)

       ONE::

       (writeln "ONE " X)

       (gotoEQ X 1 EXIT:)

       TWO::

       (writeln "TWO" )

       (goto ONE:)

       EXIT::

       (writeln "foo EXIT" ))   Returns   #<Agent 2195>

The invocation of foo produces the following console output.

    (foo 1)   Returns   true

    console   ==>   TWO

    console   ==>   ONE 1

    console   ==>   foo EXIT

 

Notes & Hints

[...under construction...]

if

The if special form selects one of two expressions to evaluate based upon the value of a (testClause) expression. If the (testClause) evaluates to true, then the (thenClause) expression is evaluated; otherwise, the (elseClause) expression is evaluated. The (testClause) and (thenClause) expressions are mandatory. The (elseClause) expression is optional. The (thenClause) and (elseClause) expressions may be preceded by optional then and else keywords for readability.

 

Type:       Function

 

Syntax examples

 

       (if (testClause) then (thenClause) else (elseClause))   ; Generates efficient code

       (if (testClause) (thenClause) (elseClause))   ; Generates efficient code

 

       (if (testClause) then (thenClause))   ; Generates efficient code

       (if (testClause) (thenClause)); Returns false when testClause fails

 

Arguments


(testClause) An expression that returns a Boolean value.
then Optional Keyword.
(thenClause) The expression to be executed if the test clause returns true.
else Optional Keyword.
(elseClause) The expression to be executed if the test clause does NOT returns true.
Returns Returns the value of the expression evaluated.

 

When To Use

Use the if special form when conditional execution of expressions is essential for your application program.

Use the if special form with the then keyword to generate efficient code without returning false when the test clause fails.

 

Example 1

Here are just a few examples of the if special form in action.

 

    (if (> 3 2) then 'YES else 'NO)   Returns   'YES

    (if (> 2 2) then 'YES else (+ 1 2))   Returns   3

    (if (> 2 3) 'YES)   Returns   false

    (if (> 2 3) then 'YES)   Returns   ...undefined...

    (if (and (icompareLT 2 3) (icompareGT 3 2)) 'YES 'NO)   Returns   'YES

    (if (compareGT 2 3) 'YES (+ 3 4))   Returns   7

 

Notes & Hints

The if special form is similar to the cond special form, except the cond special form supports more than two choices of clauses.

let

The let special form extends the current environment and evaluates the expressions (exp...) in the extended environment. The let special form evaluates the initial expressions (init). The current environment is then extended to include the specified variables (var). The initial expressions (init) are then bound to the proper variables (var). The expressions (exp) are evaluated from left to right, and the value of the final expression is returned.

 

Type:       Special Form

 

Syntax examples

 

       (let ((var init)... ) exp...)

 

Arguments


var Variable name
init Constant expression with which to initialize the variable.
exp One or more Lisp expressions.
Returns The expressions are evaluated from left to right and the value of the final expression is returned.

 

When To Use

Use the let form when a series of expressions need to be extended with additional local variables.

 

Example 1

Here are just a few examples of the let special form in action.

 

    (let ((X 2) (Y 3)) (* X Y))   Returns   6

    X   Returns   6

    (let ((X 2) (Y 3))

       (let ((foo(lambda(Z) (+ X Y Z))) (X 7))   Returns   #<Agent 281>

    (foo 4)   Returns   9

    X   Returns   6

 

Notes & Hints

The let special form always extends either the global environment or the persistent environment of the enclosed lambda expression. For instance:

    (let ((X 2)) (lambda() true))

Is the equivalent of the following.

       (lambda() pvars:((X 2)) true)

 

lisp

The lisp function performs normal Agent Information Server lexical analysis on the (inputString) argument. The input argument must be a string containing a valid simple or compound Lisp expression. The output of the lisp function is an Agent Information Server parse tree List containing Lisp lexical and semantic tokens. Normal Lisp strings are passed to the lisp function, whose output is passed to the compile function. The final result, which is produced by compile, is an executable Agent Object ready to perform its assigned tasks.

This two-step process allows the use of plug-n-play parsers, thus permitting Agent Information Server to operate with alternate programming languages. The lisp function looks for any directive such as #name# in the very first character positions of the input string. The presence of such a directive will cause the lisp parser to pass control to the global variable name on the assumption that this is an alternate parser. Alternate AIS parser must produce an AIS parse tree list like the lisp function does

If the optional agent argument (anAgent), is present, the input source string is converted into a Token Vector and stored in the Sc property of the Agent (see the disassemble Function). This allows the original source to be stored with the agent after compilation.

Normal Lisp lexical analyzers recognize tokens separated by white space.

       (lisp ?1 + 2?)   Returns   three tokens: '(1 + 2)

       (lisp ?1+2?)   Returns   one token: '1+2

If the optional arithmetic: argument is passed, it causes the normal Lisp names to be separated by the arithmetic operators + - * / < > =.

       (lisp ?1 + 2?)   Returns   three tokens: '(1 + 2)

       (lisp ?1+2?)   Returns   three tokens: '(1 + 2)

If the optional extended: argument is passed, the normal Lisp lexical analysis is altered as follows:

       (lisp ?(1 + 2)? extended:)    Returns   five tokens: '(|(| 1 + 2 |)|)

       (lisp ?1+2?)   Returns   three tokens: '(1 + 2)

 

Type:       Function

 

Syntax examples

 

       (lisp inputString)

       (lisp inputString anAgent)

       (lisp inputString extended:)

       (lisp inputString anAgent extended:)

       (lisp inputString arithmetic:)

       (lisp inputString anAgent arithmetic:)

 

Arguments


inputString Must be a valid Lisp string. If the string begins with #agentName# where AgentName is predefined Agent, the entire input string will be passed to the Agent which will perform the lexical analysis.
anAgent (Optional) The name of the agent that will be associated with the result of the lexical analysis.
extended: (Optional) Converts the lisp function into a lexical analyzer for simple expressions.
arithmetic: (Optional) Causes the normal Lisp names to be separated by the arithmetic operators + - * / < > = .
Returns An executable Agent object.

 

When To Use

Use the lisp function when parsing a Lisp string is required. This function will perform full Lisp parsing or even elementary lexical parsing

 

Example 1

Here is an example of the lisp function in action.

 

       ((compile (lisp ?(lambda(x) (+ x 2))?) 10)   Returns   12

       (lisp ?(1 + 2)?)   Returns   three tokens: '(1 + 2)

       ((compile (lisp ?#javaScript#function(x) {return(x + 2);}?) 10)   Returns   12

 

Notes & Hints

The lisp function can be used as an AIS Lisp parser or as a redirector to any number of other user defined languages.

loop

The loop Special Form performs fast numeric iteration. The specified variable (var) is the index of the iteration. The (init) expression forms the initial value for (var) at the start of the iteration. The (step) expression forms the value that is added to the (var) at the start of the next iteration

The (final) expression is compared to the (var) at the start of each iteration. If the to keyword is used, then the iterations will continue as long as (var) is less than or equal to (final). If the until keyword is used, then the iterations will continue as long as (var) is less than (final). During each iteration, each (stmt) is evaluated in order. Next, the (step) value is added to the (var)

If the (step) value is positive, iteration stops when the var is greater than (final). If the (step) is negative, iteration stops when the (var) is less than (final). If the (step) is omitted, the step value is assumed to be 1, and iteration stops when the (var) is greater than (final).

 

Type:       Special Form

 

Syntax examples

 

       (loop for var from init to final by step do stmt...)

       (loop for var from init until final by step do stmt...)

       (loop for var from init to final do stmt...)

       (loop for var from init until final do stmt...)

 

Arguments


var Index Variable.
from Mandatory keyword.
init Initial value of the index variable (must be an Integer).
to/until Mandatory keyword (must be either to or until.
final Max value of the index variable. Must be an Integer.
by Optional keyword.
step The step value added to the index variable after an iteration (must be an Integer).
do Optional keyword.
stmt Multiple Lisp expressions (must be at least one statement).
Returns The final value of the (var) variable after exiting from the loop.

 

When To Use

Use the loop special form when sequential integer iteration is advisable for your application program.

 

Example 1

Here are two examples of the loop form in action.

    (loop for n from 1 to 10 by 1 do (display " " n))   Returns   11

    Console   ==>   1 2 3 4 5 6 7 8 9 10

    (loop for n from 1 until 10 by 1 do (display " " n))   Returns   10

    Console   ==>   1 2 3 4 5 6 7 8 9

 

Notes & Hints

For correct operation, the loop special form's control variables: var, init, final, and step must be integer variables. The loop special form uses fast integer virtual machine instructions to update its control operations: initializing the var (loop index variable), incrementing the var, (adding step to var), and comparing the values of var and final (the termination value).

morph

The morph Function performs normal Agent Information Server macro substitution on the input argument, (input). The input argument (input) may be any Lisp form or forms enclosed in a list. Often the morph function receives the output of the lisp function. The output of the morph function is a list, which has been transformed by macro substitution. Often the output of morph is input to the compile function; however, the morph function is also used to perform rule-based transformations on list objects.

The second argument (altRule), called the alternative rule function, is optional. If the (altRule) function is specified, this function will perform the macro substitution in place of normal AIS macro substitution rules. The (altRule) function must be a function of one argument. The morph function will repeatedly send the (altRule) function every sub-list within the original input. If the (altRule) function wishes to pass a sub-list without macro substitution, it should return the Boolean value false. If the (altRule) function wishes to perform macro substitution on a sub-list, it should return the transformation to be substituted in place of the original sub-list.

If the optional third argument (altFailure), is present, it may be any legal AIS value. If not present, it defaults to a Boolean value of False.

 

Type:       Function

 

Syntax examples

 

       (morph input)

       (morph input altRule)

       (morph input altRule altFailure)

 

Arguments


input A list within a list to be transformed with macro or rule-based substitution.
altRule (Optional) must be a function expecting a single argument, and it will replace the normal AIS macro substitution rules.
altFailure (Optional) The value to be recognized by morph that the substitution will not take place. If the altRule function returns the altFailure value, the morph function will not substitute. If the altRule function returns a value other than the altFailure value, morph will perform the substitution. If the alfFailure argument is not present, morph will assume that the failure value is the Boolean value False
Returns A list which has been transformed by macro substitutions.

 

When To Use

Use the morph function when macro transformation of a list is essential to your application program.

 

Example 1

Simple Macro substitution using morph.

    (morph '((++ x)))   Returns   '(setq x (+ x 1)) ;; Note that the ++ is a built-in macro

    (morph 1)   Returns   1

    (morph '(1))   Returns   1

    (morph '((*= x y)))   Returns   '(setq x (* x y)) ;; Note that the *= is a built-in macro

 

Example 2

Macro substitution using an alternative rule function (altRule) and alternative failure (altFailure) options.

    (defun foo(x)

       (cond

         ((and (= (length x) 2) (= x[0] add1:) (isNumber x[1])) (+ x[1] 1))

         ((and (= (length x) 3) (= x[0] +:) (isNumber x[1]) (isNumber x[2])) (+ x[1] x[2]))

         (else _failure:)))   Returns   #<Agent 729>

    (morph '(divi (+ (add1 34) 5) n) foo _failure:)   Returns   (divi 40 n)

 

What happens

   First morph sends the innermost proper sublist to foo = > (foo '(add1 34)).

   The result of (foo ?(add1 34)) => 35, is not the altFailure value _failure, so morph substitutes.

   After substitution, the list appears as follows: '(divi (+ 35 5) n).

   Next morph sends the next innermost proper sublist to foo = > (foo ?(+ 35 5)).

   The result of (foo ?(+ 35 5) => 40, is not the altFailure value _failure, so morph substitutes.

   After substitution, the list appears as follows: '(divi 40 n).

   Next morph sends the next innermost proper sublist to foo = > (foo '(divi 40 n)).

   The result of (foo '(divi 40 n) => _failure:, is the altFailure value _failure.

   There are no more proper sublists, so the final morphed list appears as follows: '(divi 40 n).

Notes & Hints

The morph function can be used to built a rule-based list transforming forward production engine (see rulesAgent).

myself

The myself Special Form returns the currently evaluating Agent object.

 

Type:       Special Form

 

Syntax examples

 

       (myself)

 

Arguments


Returns The evaluating executable Agent object itself.

 

When To Use

Use the myself special form when the identity of the current agent object is required.

 

Example 1

Here is an example of the myself special form in action.

 

    (defun foo() (myself))   Returns   #<Agent 888>

    (foo)   Returns   #<Agent 888>

 

Notes & Hints

The myself special form is necessary for an executing agent to gain access to its own object identity.

not

The not function returns the Boolean complement of the argument. For all arguments, the not function returns false if and only if the argument (arg) is true. If the argument (arg) is false, the not function returns true.

 

Type:       Function

 

Syntax examples

 

       (not arg)

 

Arguments


arg A boolean expression to be complemented.

 

When To Use

Use the not function when complementing a boolean expression is required for your application program.

 

Example 1

Here are just a few examples of the not function in action.

 

    (not false)   Returns   true

    (not (= 2 2))   Returns   false

    (not (+ 2 2))   Returns   true

 

Notes & Hints

The not function is very useful in the succint implementation of many if special form conditions.

onError

The onError Special Form assigns an error event handler function (anAgent). The scope of the onError special form is limited to the scope of the current executing Agent. Any error events, occurring during the scope of the current executing Agent, will result in the specified error event handler Agent being invoked.

The specified error event handler Agent (anAgent), must be a function of one argument. The error event is converted into a text object and passed to the error event handler function.

 

Type:       Special Form

 

Syntax examples

 

       (onError anAgent)

 

Arguments


anAgent The specified error event handler Agent (anAgent) must be a function of one argument.
Returns true

 

When To Use

Use the onError Special Form to define an error handler function for your program.

 

Example 1

Here follows a simple example of the onError special form in action.

 

    (defun foo()

       (defun errHandler(err) (append "foo got the following error: " err))

       (onError errHandler)

       (error "badFoo"))   Returns   #<Agent 194>

    (foo)   Returns   "foo got the following error: badFoo"

 

Notes & Hints

The onError special form is an important tool for error recovery in executable Agent objects.

or

The or Special Form evaluates each expression from left to right, returning the value true at the first expression that is true. Any remaining expressions are not evaluated. If no expression returns true, the value false is returned. If no expressions are specified, the value false is returned.

 

Type:       Special Form

 

Syntax examples

 

       (or exp...)

 

Arguments


exp... Any Number of boolean expressions.
Returns Returns the value true at the first expression that is true. Any remaining expressions are not evaluated. If no expression returns true, the value false is returned. If no expressions are specified, the value false is returned.

 

When To Use

Use the or Special Form to evaluate a group of expressions, and determine if any one expression in the aggregate is true.

 

Example 1

Here are just a few examples of the or special form in action.

 

    (or (= 12 12) (> 2 1))   Returns   true

    (or (= 24 24) (= 1 1))   Returns   true

    (or 1 2 3 4 5)   Returns   false

    (or)   Returns   false

 

Notes & Hints

The or special form is an important tool in succinctly expression if conditionals.

parse

The parse function converts a string value into a numeric, date, vector, or other value. The parse function converts the string according to the built-in Lisp parsing rules. If the string cannot be recognized, by one of the built-in Lisp parsing rules, the original string, without change, is returned.

 

Type:       Function

 

Syntax examples

 

       (parse string)

 

Arguments


string The converted value of the string. If the string cannot be correctly parsed, the original string argument is returned.
Returns Returns the converted value of the string . If the string cannot be correctly parsed, the original string argument is returned.

 

When To Use

Use the parse function when a Lisp constant is to be recognized from an input string.

 

Example 1

These examples show how a string may be parsed, using the built-in Lisp parsing rules. Each of the examples is parsed and converted, except the last example. It cannot be recognized, and the original string is returned.

 

    (parse "3.141592")   Returns   3.141592

    (parse "#Jan,19,1993")   Returns   #Jan,19,1993

    (parse "#(1 2 3)")   Returns   #<Vector 2194>

    (parse "23Hello")   Returns   "23Hello"

 

Notes & Hints

The parse function allows Lisp constants to be quickly recognized from strings.

quote

The quote Special Form expands its arguments without evaluation of symbols, numbers, constants, or lists. The quote special form returns a list constructed from the specified argument expressions. The newly constructed list is always returned. The quote special form returns its argument expressions unevaluated as constants.

 

Type:       Special Form

 

Syntax examples

 

       (quote expression...)

 

Arguments


expressions... One or more Lisp expressions.
Returns The unevaluated expressions returned as constants.

 

When To Use

Use the quote special form whenever a list is to be interpreted as constant.

 

Example 1

Here are just a few examples of the quote special form in action.

 

    (defun foo(x) (length x))   Returns   #<Agent 291>

    (setq x (new Vector: 3 1 2 3))   Returns   #(1 2 3)

    x   Returns   #(1 2 3)

    (quote x)   Returns   x

    (foo x)   Returns   3

    (foo (quote x))   Returns   1

    (quote (foo x))   Returns   (foo x)

 

Notes & Hints

The quote special form has an equivalent short hand form in the ' operator.

refmacro

The refmacro special form invokes a member macro (macroName) from its parent agent. The macro invocation may include 0 or more arguments. The refmacro special form can only be used on a macro that has been installed in the parent agent and is only invoked during compile time.

 

Type:       Special Form

 

Syntax examples

 

       ((refmacro name macroName) args...)

       (name@macroName args...)

 

Arguments


name The name of the parent agent (must be a Symbol).
macroName The name of the child macro to be invoked (must be a Symbol).
arg1... (Optional) Up to twenty arguments to be sent along with the message.
Returns The result of invoking the child macro agent on the specified arguments.

 

When To Use

Use the refmaco special form when a child macro agent is to be invoked during compilation.

 

Example 1

Here are just a few examples of the colon operator in action.

 

    (defun foo(x) pvars:(v len) (setq v x))   Returns   #<Agent 291>

    (defmacro foo:len(self) pvars:(v len) (macroReplace self '(length (ref |Gv:foo| v))))

    (setq x (new Vector: 3 1 2 3))

    (foo x)

    x(foo@len foo)   Returns   3

 

return

The return Special Form immediately returns the specified argument (exp) to the caller. The current Agent gives up control and returns to its caller.

 

Type:      Function

 

Syntax examples

 

       (return exp)

 

Arguments


exp Any Lisp expression.
Returns Immediately evaluates the expression, returns the value and resumes execution of the caller function.

 

When To Use

Use the special form

 

Example 1

[...under construction...]

 

    (begin (return 1) 2)   Returns   1

    (begin (return (+ 2 3)) 2)   Returns   5

 

Notes & Hints

The return special form allows premature return from an agent.

send

The send special form sends a message (msgName) to an object and causes the corresponding message agent to be invoked. The agent invocation may include 0 or more arguments. The send special form can only be used on a method that has been installed in the Methods Dictionary for an object via the defmethod macro or the addMethod function. The Methods Dictionary for any Agent Information Server native type or object contains an arbitrary number of method bindings, i.e. message name and agent name pairs. The send special form causes a lookup of the message name argument in the Methods Dictionary specific object argument. If the message name is found, the corresponding message agent attached to the message name will be invoked.

 

Type:       Special Form

 

Syntax examples

 

       (send msgName object)

       (send msgName object arg1 arg2 ?)

       (msgName:object)

       (msgName:object arg1 arg2 ?)

 

Arguments


msgName The message to be sent (must be a Symbol).
object The target object (the object that responds to the message).
arg1... (Optional) Up to twenty arguments to be sent along with the message.
Returns The result of invoking the message agent on the specified object.

 

When To Use

Use the send special form when a message is to be sent to an object.

 

Example 1

Here are several examples of the send special form in action.

 

    (defmethod Agent: square: (self x) (* x x))   Returns   #<Dictionary 1234>

    (defun foo(x) pvars:(p1) (setq p1 x))   Returns   #<Agent 634>

    (foo 10)   Returns   10

    (send square: foo foo.p1)   Returns   100

    (square:foo foo.p1)   Returns   100

 

Notes & Hints

Dissecting the send special form involves understanding the Methods Dictionary of any Agent Information Server type. The send special form is translated as a reference into the Methods Dictionary. The translation is as follows.

    (msgName:object args...)   is Identical to   ((ref (methodsOf (type object)) msgName) args?)

    (square:aNumAgent 10)   is Identical to   ((ref (methodsOf (type aNumAgent )) square: ) aNumAgent 10)

    (square:aNumAgent aNumAgent.p1)   Returns   100

    (type aNumAgent)   Returns   Agent:

    (methodsOf (type aNumAgent))   Returns   #<Dictionary 194>

    (ref (methodsOf (type aNumAgent)) square: )   Returns   #<Agent 164>

    ((ref (methodsOf (type aNumAgent )) square: ) aNumAgent aNumAgent.p1)   Returns   100

 

setq

The setq special form is a short hand form for the (set) function which assigns new values to variables. A simple set function results in a simple assignment and is completely uncomplicated. However, the set function can also be used to set a new value into a target object with indexing. When indexing is used, the results of the set function depend upon the type of target object being indexed. The result of a set function, with indexing, are complicated because we need to know the type of target object and the types of the indices. In all cases the setq special form converts easily into a longer set function call.

 

Type:       Special Form

 

Syntax examples

 

       (setq target newValue)

       (setq (ref target index1) newValue)

       (setq (ref target index1 index2) newValue)

       (setq (ref target index1 index2 index3) newValue)

 

Arguments


target The target variable to be assigned.
index1 (Optional) A target variable index.
index2 (Optional) A target variable index.
index3 (Optional) A target variable index.
newValue The new value to be assigned to the target variable.
Returns The result of setq depends upon the type of object in the target variable.

 

When To Use

Use the setq special form when a longer set function is too cumbersome.

 

Equivalence Examples

Here are several examples of the setq special form and set function equivalences.

 

    (setq target newValue)   Same As   (set 'target newValue)

    (setq target newValue)   Same As   (set target: newValue)

    (setq target newValue)   Same As   (vmmove newValue target)

    (setq (ref target index1) newValue)   Same As   (set target index1 newValue)

    (setq target[index1] newValue)   Same As   (set target index1 newValue)

    (setq target.index1 newValue)   Same As   (set target index1 newValue)

    (setq (ref target index1 index2) newValue)   Same As   (set target index1 index2 newValue)

    (setq target[index1 index2] newValue)   Same As   (set target index1 index2 newValue)

    (setq (ref target index1 index2 index3) newValue)   Same As   (set target index1 index2 index3 newValue)

    (setq target[index1 index2 index3] newValue)   Same As   (set target index1 index2 index3 newValue)

 

super

The super Special Form supports symbolic messaging with any number of arguments. The message argument must be an element of type Symbol, and there must be at least one argument. The action taken by the symbolic message is dependent upon the type of the first argument. The message symbol is looked up in the Methods Dictionary attached to the type's Parent type (see the defmethod Macro). If the message symbol is found, the associated Agent is invoked against the whole argument list. If the message symbol is not found, an error condition results.

 

Type:       Special Form

 

Syntax examples

 

       (super message object args...)

 

Arguments


message The symbolic name of the message to be sent.
object The object whose parent message agent is to be invoked.
args... (Optional) Up to twenty arguments.
Returns The result of invoking the parent message agent with the specified arguments.

 

When To Use

The super Special Form can only be used on a type that has been defined that is a child of a parent type. The message {message} in the argument list must that have been installed in the Methods Dictionary for the parent type via the defmethod macro or the addMethod function. The Methods Dictionary for any Agent Information Server native type or object contains an arbitrary number of method bindings, i.e. message name and agent name pairs. The super command causes a lookup of the message name argument in the Methods Dictionary for the parent type. If the message name is found, the Agent attached to the name will be invoked.

 

Example 1

This example demonstrates normal object oriented messaging in Agent Information Server. First, we define two types of objects: employees and managers. Managers inherit from employees. Each type is taught how to talk.

 

    (defclass employee: 'name 'job 'salary)

    (defmethod employee:talk(me) "I am an employee.")

    (talk:(new employee:))   Returns   "I am an employee."

    (defclass manager: include: employee: 'department)

    (defmethod manager:talk(me) "I am a manager.")

    (talk:(new manager:))   Returns   "I am a manager."

    (super talk:(new manager:))   Returns   "I am an employee."

 

Notes & Hints

The super special form can be used to send messages to the parent class of an object.

while

The while Special Form repeatedly evaluates the expression {exp...} while the test clause {test} evaluates to True. When the test clause evaluates to something other than True execution halts and this value is returned. An optional do keyword may precede the {exp...}.

 

Type:       Special Form

 

Syntax examples

 

       (while test exp...)

       (while test do exp...)

 

Arguments


test An expression returning a Boolean: true or false.
exp... One or more Lisp expressions to be executed while the test expression is true.
Returns Always returns the final result of the test expression.

 

When To Use

Use the while special form to iterate an expression or set of expressions while a test condition is True. The test clause is always evaluated first.

 

Example 1

Here are just a few examples of the while special form in action.

 

    (setq Y 10)   Returns   10

    (while (> Y 0) do (setq Y (- Y 1)))   Returns   false

 

Notes & Hints

The while special form is used to iterate an expression or set of expressions while a test condition is True. The test clause is always evaluated first.