A form is anything which is to be evaluated .
Lisp is formed of two things : atoms and cons .
An atom
is anything which is not a cons
, a cons
holds two references.
A list
is formed of zero or more cons
, where the second element of each cons
, is a reference to the next cons
, and the last element of the last cons
is either a reference to the nil
element , which represents the empty list ()
, or nothing , or the last element of the last cons
is a reference to an atom . In the latter case , this list is called a dotted list . The elements of a list , are enclosed between a left parenthesis (
, and a right one )
This being said , a form or what can be evaluated in lisp , is either an atom
or a cons
, or more generally , instead or saying a cons
, a list
.
Table of Contents
Evaluating atom forms
An atom form can be either , a self evaluating atom , or it can be a symbol .
Self evaluating atoms
If the form is an atom , an atom can be an atom which evaluates to itself , hence the value of evaluating the atom form , is the atom itself .
As an example , when evaluating a number such as 1
, it evaluates to 1
, or when evaluating a string such as "Hello world "
, it evaluates to "Hello world "
.
> 1 ;;;evaluating 1 , yields ;;;1 . 1 > "Hello world" ;;;evaluating "Hello world" , ;;;yields "Hello world" . "Hello world"
Symbols
If the form is an atom , an atom can also be a symbol . A symbol has , among other things , a name , a function property , and a value property .
If the form , is just a symbol , then what is evaluated is its value property . Some symbols evaluate to themselves , for example nil
which is the empty list ()
, are both symbols , that evaluates to themselves .
>(symbolp nil ) ;;;symbolp checks if the passed ;;;argument is a symbol , it ;;;returns true , since nil ;;;is a symbol . T > nil ;;;nil evaluates to itself nil > (set 'ip "192.168.0.1" ) ;;;set the value property of ;;;the symbol ip to the string ;;;192.168.0.1 . ip is quoted ;;;using ' as not to be evaluated . > ip ;;;ip is evaluated , this returns ;;;the attribute value , which is : "192.168.0.1"
Evaluating list forms
If what is to be evaluated is a non empty list , hence a list which contains some elements , then this list is called a compound form . The empty list ( )
is a symbol , and it evaluates to itself .
A list , depending on the first element , that it has , is called either : a function form , a lambda form , a macro form or a special form .
What is a function form ?
A function performs a computation , such as an addition , or a regular expression matching .
A function form is just a non empty list , which has as a first element , a symbol , which has a function property , that defines a function .
How a function form is evaluated , is that first the remaining elements of the list , known as the cdr
of the list , are evaluated one after another , from left to right in order . Once their evaluation is done , their evaluation is applied to the function .
The standard does not specify , if the symbol which contains the function definition , is evaluated before, or after , or in between , the evaluation of the arguments .
> (+ 1 pi ) ;;;This is a function form , ;;;+ is a symbol , which has ;;;its function property defining ;;;a function . ;;;First the remainder elements of ;;;the list are evaluated from left ;;;to right , one after the other . ;;;1 evaluates to 1 . ;;;pi is a symbol , its value property ;;;is evaluated , this returns : ;;; 3.1415926535897932385L0 . ;;;The standard does not specify , ;;;when symbol + is evaluated . ;;;Evaluating the symbol + , returns ;;;its function definition . ;;;Once arguments and function definition ;;;evaluation is done , the function ;;;is called with the evaluated arguments . ;;;The addition of 1 and ;;; 3.1415926535897932385L0 , is ;;;equal to 4.1415926535897932383L0 . 4.1415926535897932383L0
To check if the function property , of a symbol is of a function type , functionp
can be used , this is not the same as checking , if a symbol has its function property bounded , in this case fboundp
can be used .
>(functionp '+ ) ;;;' is used to quote a ;;;symbol , as not to be ;;;evaluated . ;;;The symbol + is not ;;;of type function , it ;;;is a symbol which has ;;;some properties . NIL >(functionp #'+ ) ;;;#' returns the value ;;;of the property : function ;;; of a symbol . ;;;The function property of ;;;+ is of a function type . T >(fboundp '+ ) ;;;Checks if the symbol + ;;;has its property : function ;;;bounded . T
What is a lambda form ?
A lambda form , is a non empty list , which has as a first element , a lambda expression .
A lambda expression is a function , which has no name , and is defined by using a list , which first element is the symbol lambda
, followed by a list , that contains the function parameters , known as , a lambda list , a lambda list can be empty , as such the function receives no arguments . The lambda list is followed by zero or more optional forms , which constitutes the function body . If the lambda function , has no body , it just returns nil
, otherwise it returns the value of the last evaluated form .
The evaluation of a lambda form , is equivalent to using funcall
. What this means , is that since funcall
is a function , all its arguments are first evaluated from left to right , hence the lambda expression is first evaluated , followed by the remainder elements of the list , finally funcall
will apply the gotten function , from the lambda expression , to the evaluated arguments , and returns the result .
> ((lambda (x ) (* x x ) ) 2 ) ;;;This is a lambda form , since ;;;the first element of the list ;;;is a lambda expression . ;;;The lambda expression is first ;;;evaluated to get its function ;;;definition . ;;;The second element of the form , ;;;is 2 , it evaluates to itself , ;;;which is 2 . ;;;The gotten function is applied ;;;to the argument 2 , this ;;;returns 4 . 4
What is a macro form ?
A function performs a computation , such as an addition , or sorting some elements , whereas a macro function , returns another form to be evaluated , in other words , it returns a new program .
A macro form , is a non empty list , which has as a first element a symbol , which has its function property , defining a macro .
To check if the function property of a symbol , defines a macro , macro-function
can be used . macro-function
returns nil , if the property function of a symbol , does not define a macro .
> (defmacro sub(var ) `(- ,var 1 ) ) ;;;Define the symbol sub , ;;;function property with ;;;a macro definition . SUB >> (macro-function '+ ) ;;;The property function of the ;;;symbol + , is not a macro ;;; definition , hence ;;; macro-function returns NIL . NIL > (macro-function 'sub ) ;;;The symbol sub function property ;;;is a macro definition , hence ;;;macro-function does not return ;;;nil . #<FUNCTION SUB (SYSTEM::<MACRO-FORM> SYSTEM::<ENV-ARG>) (DECLARE (CONS SYSTEM::<MACRO-FORM>)) (DECLARE (IGNORE SYSTEM::<ENV-ARG>)) (IF (NOT (SYSTEM::LIST-LENGTH-IN-BOUNDS-P SYSTEM::<MACRO-FORM> 2 2 NIL)) (SYSTEM::MACRO-CALL-ERROR SYSTEM::<MACRO-FORM>) (LET* ((VAR (CADR SYSTEM::<MACRO-FORM>))) (BLOCK SUB `(- ,VAR 1))))>
A macro form is evaluated , by first evaluating the macro , and expanding it , replacing the macro form . The arguments are evaluated as part of the expanded form .
> (defmacro sub(var ) `(- ,var 1 ) ) ;;;Defines the function property ;;;of the symbol sub , as being ;;;a macro defintion . > (sub pi) ;;;sub function property , is a macro ;;;definition , hence what happens first, ;;;is that sub is expanded , and the form ;;;is replaced , by sub expansion . ;;;pi as a symbol , is not evaluated , ;;;first , it is only evaluated , ;;;when evaluating the replacement ;;;form , which is now : ;;;(- pi 1 ) ;;;This is a function form , ;;;the cdr of the list , ;;;which is its remainder , ;;;is evaluated . ;;; pi is evaluated to get ;;;3.1415926535897932385L0 ;;;1 is evaluated to 1 . ;;;The standard does not specify , ;;;when the symbol - is evaluated , ;;;to get its function definition . ;;;It can be , before , after , or ;;;in between evaluating the arguments. ;;;Once the elements of the list ;;;are evaluated , the function ;;;- is applied to the gotten ;;;arguments , and the returned ;;;value is 2.1415926535897932385L0 2.1415926535897932385L0
What is a special form ?
A special form , is a form , which has as its first element , a special operator . The special operators are :
block catch eval-when flet function go if labels let let* load-time-value locally macrolet multiple-value-call multiple-value-prog1 progn progv quote return-from setq symbol-macrolet tagbody the throw unwind-protect
A special form , might have a special syntax , or a special evaluation rule , for example it might not evaluate all of its arguments .
> (if t 1 pi ) ;;;In this example , pi is ;;;never evaluated , since ;;;the condition is true , ;;;hence what is evaluated ;;;is 1 , which evaluates , ;;;to itself . 1