Page Numbers: Yes X: 306 Y: 1.0" First Page: 26
Margins: Top: 1.0" Bottom: 1.3"
Heading:
STANDARD PROCEDURE GUIDE3-LISP REFERENCE MANUAL April 16, 1984
————————————————————————————————————————————
2.b. FUNCTIONS, DEFINITIONS, and CONTROL STRUCTURE
————————————————————————————————————————————
2.b.1. DEFINITIONS, FUNCTIONS, and VARIABLES
————————————————————————————————————————————
(FUNCTION E)
True just in case E designates a function.
F-Type: [ OBJECTS ] ← TRUTH-VALUESProperties: Primitive; kernel.
Examples:(FUNCTION (LAMBDA [N] (* N N)))g$TRUE
(FUNCTION ↑(LAMBDA [N] (* N N)))g$FALSE
(FUNCTION 3)g$FALSE
(DEFINE LABEL FUN)
Establishes a binding of the atom LABEL (not the designation of that atom — i.e., LABEL is in an intensional context) to the function designator (closure) that results from normalising FUN. Unlike SET, DEFINE normalises FUN in an environment in which LABEL will ultimately be bound to the result of the normalisation, to facilitate recursion. (DEFINE LABEL FUN) is usually used both to establish LABEL as the public name for the function designated by FUN, and to enables FUN to use LABEL as its own internal name for itself. Returns a handle to LABEL Puts the string "LABEL" into the comment field of the closure to which FUN normalises.
Properties:Smash-env; abnormal.
Macro:(DEFINE LABEL FUN)
W> (BEGIN (SET LABEL FUN)
(SET-COMMENT ↑LABEL (ATOM-NOTATION ↑LABEL))
’LABEL)
Examples:1> (DEFINE SQUARE (LAMBDA SIMPLE [N] (* N N)))
1= ’SQUARE
1> (DEFINE FACTORIAL
(LAMBDA SIMPLE [N]
(IF (= N 0) 1 (* N (FACTORIAL (1- N))))))
1= ’FACTORIAL
1> (FACTORIAL 6)
1= 720
(LAMBDA PATTERN BODY1 ... BODYk)
Informally, (LAMBDA PATTERN BODY1 ... BODYk) designates the function that is signified by the lambda abstraction of the formal parameters in pattern PATTERN over the BODY structures. LAMBDA is intensional in all its argument positions: neither PATTERN nor any of the BODY is normalised. More formally, (LAMBDA PATTERN BODY) normalises to the closure consisting of a designator of the current environment, and the non-normalised structures PATTERN and BODY. If k>2, the BODYi are wrapped in a (BEGIN ... ) block.
Properties:Kernel; cons; abnormal.
Examples:(LAMBDA [A B] (* A B))g{simple closure ... }
((LAMBDA [N] (+ N N)) 4)g8
1> ((LAMBDA [N] (PRINT PS "Hello") N) 4) Hello
1= 4
(RLAMBDA PATTERN BODY1 ... BODYk)
RLAMBDA is used to define reflective procedures; its arguments are exactly as for LAMBDA, but the closure returned is reflectified.
Examples:1> (DEFINE BOUND
(RLAMBDA [CALL ENV ESC CONT]
(CONT (IF (= "unbound variable"
(BINDING
(DOWN (NORMALIZE (1ST (PARGS CALL))
ENV ESC ID))
’$FALSE
’$TRUE))))
1= ’BOUND
1> (BOUND (ACONS))
1= $FALSE
1> (LET [[X 3]] (BOUND ’X))
1= $TRUE
(MLAMBDA PATTERN BODY1 ... BODYk)
MLAMBDA is used to define macro procedures; its arguments are exactly as for LAMBDA, but the closure returned is macroified. When a procedure call (FOO . ARGS) is normalised and FOO designates a macro procedure, the sequence of events will be as follows: the arguments to the procedure will not be normalised; the defining environment will be extended by matching the pattern against a designator of the unnormalised arguments; the body will be normalised in this new environment; finally, the result of this normalisation will be re-normalised in the original environment.
F-Type:[ RAILS X STRUCTURES X STRUCTURES ] ← FUNCTIONS Properties: Cons.
Examples:1> (DEFINE INCREMENT
(MLAMBDA [CALL] ̀ (+ ,(FIRST (PARGS CALL)) 1)))
1= ’INCREMENT
1> (INCREMENT 5)
1= 6
(SET VAR BINDING)
SET alters the current environment’s binding of the atom VAR to be the result of normalising BINDING (in the current environment). Note that the first argument, VAR, is not normalised. Returns the result of normalising BINDING, and therefore designates the designation of BINDING.
Properties: Smash-env; abnormal.
Examples:1> (SET X (+ 2 2))
1= 4
1> X
1= 4
1> (SET X (+ X X))
1= 8
(LET [[A1 E1] ... [Ak Ek]] BODY1 ... BODYk)
Designates the designation that BODY has in an environment which is like the current environment except extended by binding the atoms Ai to the results of normalising the expressions Ei in environment the current environment. In other words all of the Ei are normalised in the same environment. It can be determined that the Ei will be normalised sequentially, but it is considered bad programming practice to depend on this fact (BEGIN should be used for explicit sequential processing). <<<currently let only lets you bind atoms, not match patterns>>>
Properties:Kernel; env; abnormal.
Macro:(LET [[P1 E1] ... [Pk Ek]] BODY)
W> ((LAMBDA [P1 ... Pk] BODY) E1 ... Ek)
Examples:(LET [[X 3] [Y 4]] (+ X Y))g7
(LET [[X 3]]
(LET [[X 4] [Y X]] (+ X Y)))g7
(LETSEQ [[P1 E1] ... [Pk Ek]] BODY1 ... BODYk)
LETSEQ is like LET except that each expression Ei+1 is normalised in the environment that results from extending the previous environment with the results of matching pattern Pi against the normalisation of Ei.
Properties:Env; abnormal.
Macro:(LETSEQ [[P1 E1][P2 E2] ... [Pk Ek]] BODY1 ... BODYk)
W> (LET [[P1 E1]]
(LETSEQ [[P2 E2] ... [Pk Ek]] BODY1 ... BODYk))
Examples:(LET [[X 3]]
(LETSEQ [[X 4] [Y X]] (+ X Y)))g8
(LETREC [[V1 E1] ... [Vk Ek]] BODY1 ... BODYk)
Like LET and LETSEQ except that each expression Ei is normalised in the environment that results from extending the original environment with the results of binding all of the variables Vi against the normalisations of their Ei. The Ei are all normalised, in other words, in the environment of the overall expression; they should not depend on the bindings of any of the Vi.
Properties:Env; abnormal.
Macro:(LETREC [[V1 E1][V2 E2] ... [Vk Ek]] BODY1 ... BODYk)
W> (LET [[V1 "unbound"][P2 "unbound"] ... [Vk "unbound"]]
(BEGIN (SET V1 E1)
(SET V2 E2)
...
(SET Vk Ek)
BODY1
...
BODYk)))
Examples:(LETREC [[EVEN (LAMBDA [N]
(IF (= N 0) $T (ODD (1- N))))]
[ODD (LAMBDA [N]
(IF (= N 0) $F (NOT (EVEN N))))]]
[(EVEN 2) (ODD 2)])g[$TRUE $FALSE]