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
(defclone ... ) Clone (user defined) declaration statement
(lambda ... ) Lambda(function) building statement
(defun ... ) Lambda(function) declaration statement
(defchild ... ) Lambda(function) declaration statement
(defriend ... ) Lambda(function) declaration statement
(deforphan ... ) Lambda(function) declaration statement
(defmethod ... ) Lambda(method) declaration statement
(defvm ... ) Lambda(virtual machine) declaration statement
regs:(...) Lambda(register) declaration statement
vars:(...) Lambda(variable) declaration statement
svars:(...) Object(variable) declaration statement
pvars:(...) Lambda(variable) declaration statement
cvars:(...) Lambda(variable) declaration statement

Lambda Declaration

The lambda special form creates and returns an instance of an Lambda object. Each Lambda 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 Analytic Information Server across the Internet. AIS Lisp provides several ways to declare an Lambda. The lambda function supports the creation of unbound-unnamed Lambdas. There are multiple ways of declaring bound-named Lambdas as follows.

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

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

Variable Declarations

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

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 Analytic Information Server Lambda 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 Lambda'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 Lambda receives its arguments on the stack. The arguments are received and bound to the proper arguments.

 

Interface Declarations

AIS Lisp supports the declaration of Lambda interfacesas well as the declaration of event keywords. The keyword faces: declares the interfaces feature Structure of the Lambda. 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 Lambda is to be evaluated, by the garbage collector, when the Lambda is doomed. The Lambda?s EvalWhenDoomed element is set to true. The Lambda is always evaluated, by the garbage collector, with no arguments.

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

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

        Doomed: ;; This Lambda 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 Lambda 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 Lambda.
Returns An executable Lambda object.

parent The name of the parent Lambda into which the Lambda is to be bound.
name The name to which the Lambda 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 Lambda.
Returns An executable Lambda object.

typeSymbol The name of the owner data type into whose method list the Lambda is to be bound.
name The name to which the Lambda 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 Lambda.
Returns An executable Lambda object.

 

When To Use

Use the lambda special form and other Lambda declaration forms when an Lambda 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 Lambda.

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

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

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

Here the Lambda is invoked with the argument 4.

    (foo 4)Returns   8

Here the Lambda is immediately invoked with the argument 4.

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

 

Example 2

Here a slightly more complex Lambda 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 Lambda is invoked with the arguments 4 5 and 71.

    (sumNums 4 5 71)   Returns   80

 

Example 3

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

    (defun foo(x)

       pvars:(y)

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

       (setq y x))

Here we invoke the parent Lambda foo.

    (foo 9)   Returns   9

Here we invoke the child Lambda sum.

    (foo.sum 2)   Returns   11

 

Notes & Hints

The scope of variables in nested Lambdas depends upon the following Lisp compilation rules: Nested Lambdas do not share either their argument or their temporary variables. The argument and the temporary variables are always limited in scope to the immediate Lambda object. A nested Lambda both shares and extends the persistent variables (pvars) of its parents. When a variable reference is encountered, the Lisp compiler first searches the local Lambda's arguments for a match, then the searches the local Lambda's temporary variables (vars) for a match, finally searches the Lambda'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   #<Lambda 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 Lambda 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 Lambda object. When called, the Lambda 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 Lambda object may be either a root Lambda or it will be a child Lambda of any Lambda within which it is declared. Child lambda Lambdas are always registered in the pvars:() of their parent Lambda. The new Lambda may be called directly when the arguments specified in its argument list.

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

An AIS Lambda 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 Lambda'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 Lambda. 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 Lambda. 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 Lambda. 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 Lambda. 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 Lambda. 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 Lambda. 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 Lambda 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 Lambda returns the value of the final expression in the sequence.

When To Use

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

Arguments


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

Example 1

Here the Lambda 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 Lambda object, which is immediately executed. This newly minted Lambda is passed a numeric argument and a numeric result is returned.

Example 2

Here a slightly more complex Lambda 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 Lambda object, which assigned to the specified global variable name. This newly minted Lambda is passed a series of numeric arguments and a numeric result is returned.

defclass

Overview

The defclass special form creates a new Class Lambda 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 Lambda 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 Lambda may be called directly when the class itself is to be initialized. The class Lambda 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 Lambda may contain a new method which will be invoked whenever the class Lambda 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 Lambda will contain a methods list in its Interfaces section named classMethods. Also, the class Lambda 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 Lambdas of their parent class Lambda. After compilation, child class Lambdas are linked to their parent classes and to their library classes via the classNames, parent, and library properties of the class Lambda Interfaces sections. Normally, friend Lambdas of a class Lambda are NOT added to the class names list.

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

When To Use

Use this special form when a new class Lambda 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 Lambda.
Returns The new Class Lambda.

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 Lambda is destroyed. When an class Lambda object is no longer referenced, the garbage collector may choose to destroy the Lambda. Before final destruction takes place, the class Lambda will be sent a doomed message.

Each Lambda's EvalWhenDoomed property is initially set to false. Normally, garbage collecting an Lambda, causes nothing to happen (other than the destruction of the Lambda); however, if the class Lambda's EvalWhenDoomed property is set to true, then the doomed Lambda 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 Lambda is destroyed, we do not wish the log file to be left open. The class Lambda has the task of responding to the doomed event and closing the file before final destruction.

Example 2

This example shows how the class Lambda 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)

defclone

Overview

The defclone special form creates a new clone Lambda and assigns it to the specified global variable name. The clone Lambda is a partial copy of the parent Lambda

Type:              Special From

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

The new clone Lambda creates a partial copy of the parent Lambda and assigns it to the specified global variable name. The clone Lambda contains a copy of the variables as declared in the parent's svars:(), the variables as declared in the parent's pvars:(), and the variables as declared in the parent's cvars:(). The new clone Lambda does NOT share the variables as declared in the parent's faces:().

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

When To Use

Use this special form when a new class Lambda 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 Lambda.
Returns The new Class Lambda.

Example

Creating and initializing a new class of object.

(defun foo(x)

          pvars:((Number:Salary 1.0))

          (+ Salary x) ;; end of foo

         

(defclone foo:moo(x)

          pvars:((Number:Salary 10.0))

          (+ Salary x) ;; end of moo

         

(foo 24000.0))     ==>     "24001.0"

(moo 24000.0))     ==>     "24010.0"

defun

Overview

The defun special form creates a new Lambda 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 Lambda object may be either a root Lambda or it will be a child Lambda of any Lambda within which it is declared. Child defun Lambdas are always registered in the pvars:() of their parent Lambda. The new Lambda may be called directly when the arguments specified in its argument list.

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

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

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

When To Use

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

Arguments


name The symbolic name for the new Lambda (must be a Symbol).
(arg...) Zero or more argument variable declarations.
faces:(var...) (Optional)The Lambda interfaces declarations.
pvars:(var...) (Optional)The Lambda persistant variable declarations.
cvars:(var...) (Optional)The Lambda constant variable declarations.
vars:(var...) (Optional)The Lambda temporary variable declarations.
regs:(var...) (Optional)The Lambda register variable declarations.
expression... (Mandatory)One or more Lisp expressions defining the body of the Lambda.
Returns The new Lambda 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 Lambda object, containing all of the variables as declared in the pvars:() and vars:(). This newly minted Lambda is passed a numeric argument and a numeric result is returned.

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

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

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

Example 2

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

(defun myLambda(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 Lambda library can create and share a user-defined Structure template containing strongly-typed variable declarations.

(defun myLambda(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 Lambda and assigns it to the specified parent Lambda. The new child Lambda object is always assigned to the pvars:() of the specified parent Lambda. The defchild special form always returns the newly created child Lambda 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 Lambda object will be a child Lambda of the parent Lambda to which it is declared. Child Lambdas are always registered in the pvars:() of their parent Lambda, and child Lambdas always have their pvars:() as the pvars:() of their parent. Child Lambdas always have their cvars:() as the cvars:() of their parent. The new Lambda may be called directly with the arguments specified in its argument list.

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

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

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

When To Use

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

Arguments


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

Example 1

This example shows how child Lambdas 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 Lambda DOES share the same pvars:() and cvars:() variables as its parent Lambda. A friend Lambda has a different pvars:() structure from its parent Lambda, but the cvars:() structure of a friend Lambda is the pvars:() structure of its parent Lambda.

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 Lambda depending on whether the define special form is invoked outside of or inside another Lambda. 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 Lambda, the define special form assigns to the pvars:() of the parent Lambda. Note that the define special form assigns only once a compile time not every time the Lambda is executed.

defmacro

Overview

The defmacro special form creates a new Macro Lambda object, assigns it to the specified variable name and returns the newly created Macro Lambda object. The new Macro Lambda 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 Lambda object will always be registered in the global name space, and may be invoked directly in any Lisp expression. Macro Lambdas can be used to enhance any class or Lambda library. It is an AIS Lisp traditional to name all macros, in a library, after the global name of the class or Lambda 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, Lambdas are of limited capability and value. Operating in communities, Lambdas have immense value and capabilities. AIS Lisp allows individual Lambdas to be formed together into large Lambda communities of complex architecture. Lambdas can work together as classes, methods, children, friends, orphans, macros, all in increasing layers of complexity. A community of Lambdas brought together to accomplish a specific set of tasks AND which can be used as a mobile TOOL is called an Lambda library. The precise qualities which cause an Lambda community to evolve from a simple hodpodge into a useful library are qualitative. However useful Lambda libraries come in two distinctive flavors: Lambda oriented Libraries (AOP), and Object Oriented Libraries (OOP). Lambda oriented library tools present their users with a functional interface wherein data is passed to functional Lambda-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 Lambda libraries of either flavor to be created and mixed together in arbitrary layers of complexity.

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

Note: See also the lambda special form for additional information on creating Lambdas 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 Lambda of the new macro Lambda (must be a Symbol or an Lambda).
name The symbolic name for the new Macro Lambda (must be a Symbol).
(arg...) Zero or more argument variable declarations.
faces:(var...) (Optional)The Lambda interfaces declarations.
pvars:(var...) (Optional)The Lambda persistant variable declarations.
cvars:(var...) (Optional)The Lambda constant variable declarations.
vars:(var...) (Optional)The Lambda temporary variable declarations.
regs:(var...) (Optional)The Lambda register variable declarations.
expression... (Mandatory)One or more Lisp expressions defining the body of the Lambda.
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 Lambda may be as complex as required, including macro Lambdas which are complex Lambda 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 Lambda for the specified Class Lambda and adds it to the classMethods in the Interfaces section of the specified class Lambda.

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 Lambda with at least one argument (which by convention is named self). The first argument, declared for the new method Lambda, must be of the specified type typeName. The new method Lambda is added to the Methods Structure of the specified type typeName. After adding the Lambda to the Methods Structure of the specified type, the type will respond to the message named msgName by invoking the new methods Lambda. 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 Lambda adds a new function or capability to the specified Lambda class library and may be a root method or may override an existing method of the class library. The method Lambda may be called directly or it may be invoked by sending a message to any object instance of the specified class. The method Lambda 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 Lambda will contain a methods list in its Interfaces section named classMethods After compilation, the new method Lambda will be added to the methods list in the specified class Lambda. 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 Lambda.

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

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

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

When To Use

Use this macro when a class Lambda 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 Lambda 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 Lambda interfaces declarations.
pvars:(var...) (Optional)The class Lambda persistant variable declarations.
cvars:(var...) (Optional)The class Lambda constant variable declarations.
vars:(var...) (Optional)The method Lambda temporary variable declarations.
regs:(var...) (Optional)The method Lambda register variable declarations.
expression... (Mandatory)One or more Lisp expressions defining the body of the method Lambda.
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 Lambda). This newly minted copy of the class object is sent the "raise" message which invokes the raise method Lambda. 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 Lambdas. Through inheritance a newly declared class may automatically obtain many of the properties of its parent and library class Lambdas. 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 Lambda 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 Lambdas). This newly minted copy of the manager object is sent the "raise" message which invokes the raise method Lambda. 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 Lambda 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 Lambdas). This newly minted copy of the manager object is sent the "raise" message which invokes the manager's raise method Lambda. 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 Lambda and assigns it to the specified parent Lambda. The new friend Lambda object is always assigned to the pvars:() of the specified parent Lambda. The defriend special form always returns the newly created friend Lambda 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 Lambda object will be a friend Lambda of the parent Lambda to which it is declared. Friend Lambdas are always registered in the pvars:() of their parent Lambda, and friend Lambdas always have their pvars:() new an separate from the pvars:() of their parent. Friend Lambdas always have their cvars:() shared as the pvars:() of their parent. Friend Lambdas cannot see the cvars:() of their parent, and parents cannot see the pvars:() of their friend Lambdas. The new Lambda may be called directly with the arguments specified in its argument list.

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

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

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

When To Use

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

Arguments


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

Example 1

This example shows how friend Lambdas 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 Lambda does not share the same pvars:() variables with its parent; however, the cvars:() structure of a friend Lambda is the pvars:() structure of its parent Lambda.

deforphan

Overview

The deforphan special form creates a new orphan Lambda and assigns it to the specified parent Lambda. The new orphan Lambda object is always assigned to the pvars:() of the specified parent Lambda. The deforphan special form always returns the newly created orphan Lambda 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 Lambda object will be an orphan Lambda of the parent Lambda to which it is declared. Orphan Lambdas are always registered in the pvars:() of their parent Lambda, and Orphan Lambdas always have their pvars:() new an separate from the pvars:() of their parent. Orphan Lambdas always have their cvars:() new an separate from the cvars:() of their parent. Orphan Lambdas cannot see the pvars:() of their parent, and orphan Lambdas cannot see the cvars:() of their parent. Orphan Lambdas cannot see their parent. The new Lambda may be called directly with the arguments specified in its argument list.

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

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

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

When To Use

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

Arguments


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

Example 1

This example shows how orphan Lambdas 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 Lambda does not share the same pvars:() variables with its parent; and, an orphan Lambda 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 Analytic Information Server context. The defstruct special form brings the conventional object-oriented paradigm to the Analytic 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 Lambda Virtual Machine object, assigns it to the specified global variable name in the global environment, and returns the newly created Lambda Virtual Machine object. The new Virtual Machine Lambda object is assigned to the specified global variable name, and can be used to control the behavior of any other Lambda to which it is assigned.

Every AIS Lambda object must be assigned a virtual machine, which controls the behavior of the Lambda object when it is invoked. Normally, the compile function assigns the drmVirtualMachine to each Lambda object which it compiles. The drmVirtualMachine controls Lambda 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 Lambda 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, Lambdas are of limited capability and value. Operating in communities, Lambdas have immense value and capabilities. AIS Lisp allows individual Lambdas to be formed together into large Lambda communities of complex architecture. Lambdas can work together as classes, methods, children, friends, orphans, all in increasing layers of complexity. A community of Lambdas brought together to accomplish a specific set of tasks AND which can be used as a mobile TOOL is called an Lambda library. The precise qualities which cause an Lambda community to evolve from a simple hodpodge into a useful library are qualitative. However useful Lambda libraries come in two distinctive flavors: Lambda oriented Libraries (AOP), and Object Oriented Libraries (OOP). Lambda oriented library tools present their users with a functional interface wherein data is passed to functional Lambda-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 Lambda libraries of either flavor to be created and mixed together in arbitrary layers of complexity.

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

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

When To Use

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

Arguments


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

 

When To Use

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

 

Example 1

Here we create an Lambda Virtual Machine whose job is to keep a count of the number of times each of its client Lambdas 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 Lambda Virtual Machine whose last argument is always the Lambda 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 Lambda. The current Lambda 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 Lambda.

 

When To Use

The argCount special form is the only method to return the number of arguments that was passed to the current Lambda. The current Lambda 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 Analytic Information Server Lambda 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 Lambda'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 Lambdas 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 Lambdas 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 Analytic Information Server Lambda 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 Lambda'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 Analytic Information Server generic parse tree (parseTree) argument (normally the output from lisp) and returns an Lambda object. If the optional (anLambda) argument is passed, it becomes the target of the compilation and is returned; otherwise, a new Lambda object is returned. If the optional true argument is passed, the compilation always inherits the persistent variables of the optional (anLambda) argument.

 

Type:       Function

 

Syntax examples

 

       (compile parseTree)

       (compile parseTree anLambda)

       (compile parseTree anLambda true)

 

Arguments


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

 

When To Use

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

 

Example 1

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

 

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

 

Notes & Hints

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

    (lambda (n) #void)

Can be created from the following Lisp code.

    (makeLambda

       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 Lambda as an argument, invoking eval is equivalent to invoking the Lambda with no arguments.

 

Type:       Function

 

Syntax examples

 

       (eval string)

       (eval list)

       (eval Lambda)

 

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)).

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

 

When To Use

Use the eval function whenever a lisp expression or an Lambda 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 Lambdas of zero arguments.

goto

The goto special form allows Lisp Lambdas to transfer control to goto labels within an Lambda. 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 Lambda.

 

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   #<Lambda 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 Lambdas to conditionally branch to goto labels within an Lambda. 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.

  • LT    (less than)
  • LE    (less than or equal)
  • EQ    (equal)
  • NE    (not equal)
  • GE    (greater than or equal)
  • GT    (greater than)

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.

  •      (generic compare)
  • b    (bit compare)
  • c    (character compare)
  • i    (integer compare)
  • n    (number compare)

 

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 Lambda.

 

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   #<Lambda 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   #<Lambda 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 Analytic 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 Analytic 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 Lambda Object ready to perform its assigned tasks.

This two-step process allows the use of plug-n-play parsers, thus permitting Analytic 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 Lambda argument (anLambda), is present, the input source string is converted into a Token Vector and stored in the Sc property of the Lambda (see the disassemble Function). This allows the original source to be stored with the Lambda 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:

  • The lexical symbol ' is no longer a lexical quote operator, and becomes a stand-alone operator symbol.
  • The lexical symbols ' , [ ] { } ( ) ; . Become singleton (ungrouped) stand-alone operator symbols.
  • The lexical symbols ! @ # $ % ^ & * - = + | \ : < > ? / Become clustered (grouped) operator symbols.
  • The lexical constants for Money, Integer, Number, and String are still recognized as in normal AIS Lisp.
  • The lexical Lisp names are now terminated when a grouped or ungrouped operator symbol is encountered.
  • The arithmetic operators become separators.

       (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 anLambda)

       (lisp inputString extended:)

       (lisp inputString anLambda extended:)

       (lisp inputString arithmetic:)

       (lisp inputString anLambda arithmetic:)

 

Arguments


inputString Must be a valid Lisp string. If the string begins with #LambdaName# where LambdaName is predefined Lambda, the entire input string will be passed to the Lambda which will perform the lexical analysis.
anLambda (Optional) The name of the Lambda 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 Lambda 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 Analytic 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   #<Lambda 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 rulesLib).

myself

The myself Special Form returns the currently evaluating Lambda object.

 

Type:       Special Form

 

Syntax examples

 

       (myself)

 

Arguments


Returns The evaluating executable Lambda object itself.

 

When To Use

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

 

Example 1

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

 

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

    (foo)   Returns   #<Lambda 888>

 

Notes & Hints

The myself special form is necessary for an executing Lambda 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 (anLambda). The scope of the onError special form is limited to the scope of the current executing Lambda. Any error events, occurring during the scope of the current executing Lambda, will result in the specified error event handler Lambda being invoked.

The specified error event handler Lambda (anLambda), 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 anLambda)

 

Arguments


anLambda The specified error event handler Lambda (anLambda) 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   #<Lambda 194>

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

 

Notes & Hints

The onError special form is an important tool for error recovery in executable Lambda 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   #<Lambda 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 Lambda. 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 Lambda 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 Lambda (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 Lambda on the specified arguments.

 

When To Use

Use the refmaco special form when a child macro Lambda 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   #<Lambda 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 Lambda 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 Lambda.

send

The send special form sends a message (msgName) to an object and causes the corresponding message Lambda to be invoked. The Lambda 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 Analytic Information Server native type or object contains an arbitrary number of method bindings, i.e. message name and Lambda 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 Lambda 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 Lambda 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 Lambda: square: (self x) (* x x))   Returns   #<Dictionary 1234>

    (defun foo(x) pvars:(p1) (setq p1 x))   Returns   #<Lambda 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 Analytic 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:aNumLambda 10)   is Identical to   ((ref (methodsOf (type aNumLambda )) square: ) aNumLambda 10)

    (square:aNumLambda aNumLambda.p1)   Returns   100

    (type aNumLambda)   Returns   Lambda:

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

    (ref (methodsOf (type aNumLambda)) square: )   Returns   #<Lambda 164>

    ((ref (methodsOf (type aNumLambda )) square: ) aNumLambda aNumLambda.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 Lambda 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 Lambda is to be invoked.
args... (Optional) Up to twenty arguments.
Returns The result of invoking the parent message Lambda 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 Analytic Information Server native type or object contains an arbitrary number of method bindings, i.e. message name and Lambda 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 Lambda attached to the name will be invoked.

 

Example 1

This example demonstrates normal object oriented messaging in Analytic 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.