Page Numbers: Yes X: 306 Y: 1.0" First Page: 62
Margins: Top: 1.0" Bottom: 1.3"
Heading:
STANDARD PROCEDURE GUIDE3-LISP REFERENCE MANUALJanuary 25, 1983
————————————————————————————————————————————
9.h. FUNCTION DEFINITION and VARIABLE BINDING
————————————————————————————————————————————
(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 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. In other words, (DEFINE LABEL FUN) establishes LABEL as the public name for the function designated by FUN, and also enables FUN to use LABEL as its own internal name for itself. Returns a handle to LABEL. DEFINE employs both SET and Y-OPERATOR (q.q.v.).
Properties:Protected; smash-env; abnormal.
Y-Type:[ ATOMS X CLOSURES ] ← HANDLES
Examples:1> (DEFINE SQUARE (LAMBDA SIMPLE [N] (* N N)))
=> ’SQUARE
1> (DEFINE FACTORIAL
(LAMBDA SIMPLE [N]
(IF (= N 0) 1 (* N (FACTORIAL (1- N))))))
=> ’FACTORIAL
1> (FACTORIAL 6)
=> 120
Semantics:S(E0("DEFINE),E,F,C) = l ...
———————————————————
(Y-OPERATOR FUN)
(Y-OPERATOR FUN) designates a function with the property that (FUN (Y-OPERATOR FUN)) also designates that same function. In other words, (Y-OPERATOR FUN) ia a fixed point of the function designated by FUN. FUN must designate a mapping from functions to functions. This fixed point operator is used in defining recursive procedures (see the definition of DEFINE in section 8).
Properties:Protected.
F-Type:[ FUNCTIONS ] ← FUNCTIONS
Examples:1> (SET FACTORIAL
(Y-OPERATOR
(LAMBDA SIMPLE [SELF]
(LAMBDA SIMPLE [N]
(IF (= N 0) 1 (* N (SELF (1- N))))))))
=> ’OK
1> (FACTORIAL 6)
=> 120
Semantics:S(E0("Y-OPERATOR),E,F,C) = l ...
———————————————————
(Y*-OPERATOR FUN)
Y*-OPERATOR is a generalisation of Y-OPERATOR that is useful in defining multiple mutually recursive procedures.
F-Type:[ {FUNCTIONS}* ] ← SEQUENCES
Examples:1> (SET EVEN&ODD
(Y*-OPERATOR
(LAMBDA SIMPLE [EVEN ODD]
(LAMBDA SIMPLE [N]
(IF (= N 0) $T (ODD (1- N)))))
(LAMBDA SIMPLE [EVEN ODD]
(LAMBDA SIMPLE [N]
(IF (= N 0) $F (EVEN (1- N)))))))
=> ’OK
1> ((1ST EVEN&ODD) 2)
=> $T
1> ((2ND EVEN&ODD) 2)
=> $F
Semantics:S(E0("Y*-OPERATOR),E,F,C) = l ...
——————————————————
(LAMBDA TYPE PAT BODY)
Informally, an expression of the form (LAMBDA TYPE PAT BODY) designates the function of type TYPE (typically SIMPLE, REFLECT, or MACRO) that is signified by the lambda abstraction of the formal parameters in pattern PAT over the expression BODY. LAMBDA is intensional in its second and third argument positions: neither PAT nor BODY is normalised. More formally, (LAMBDA TYPE PAT BODY) designates the result of applying the function designated by TYPE to three arguments: a designator of the current environment, and the two expressions PAT and BODY (un-normalised).
Properties:Protected; kernel; cons; abnormal.
Y-Type:[ CLOSURES X STRUCTURES X STRUCTURES ] ← CLOSURES
Examples:1> (LAMBDA SIMPLE [A B] (* A B))
=> {closure: SIMPLE {global} [A B] (* A B)}
1> ((LAMBDA SIMPLE [N] (+ N N)) 4)
=> 8
1> ((LAMBDA REFLECT [ARGS ENV CONT] ARGS) . XXX)
=> ’XXX
2>
Semantics:S(E0("LAMBDA),E,F,C) = l ...
———————————————————
(SIMPLE DEF-ENV PAT BODY)
This procedure together with REFLECT, MACRO, REFLECT!, E-MACRO, and E-REFLECT are most useful as the TYPE specification in the context (LAMBDA TYPE PAT BODY). SIMPLE is used to define simple procedures. When a procedure call (FOO . ARGS) is normalised at level N and FOO designates a simple procedure, the sequence of events will be as follows: ARGS will be normalised in the current level N environment; the defining environment, DEF-ENV, will be extended by matching the pattern, PAT, against the arguments; finally, the body, BODY, will be normalised at level N in this new environment.
Properties:Protected; kernel; cons.
F-Type:[ RAILS X STRUCTURES X STRUCTURES ] ← FUNCTIONS
Examples:(SIMPLE ’[[’X ’1]] ’[] ’X)g{closure: SIMPLE [[’X ’1]] [] X}
((SIMPLE ’[[’X ’1]] ’[] ’X))g1
((SIMPLE ↑GLOBAL ’[X] ’(+ X 2)) 99)g101
((SIMPLE ’[] ’[X] ’(ACONS)))g{ERROR: Unbound variable ACONS.}
Semantics:S(E0("SIMPLE),E,F,C) = l ...
———————————————————
(REFLECT DEF-ENV PAT BODY)
REFLECT is used to define reflective procedures. When a procedure call (FOO . ARGS) is normalised at level N and FOO designates a reflective procedure, the sequence of events will be as follows: the defining environment, DEF-ENV, will be extended by matching the pattern, PAT, against a designator of the unnormalised ARGS, the level N environment, and the current level N processor continuation; lastly, the body, BODY, will then be normalised at level N+1 in this new environment.
Properties:Protected; kernel; cons.
F-Type:[ RAILS X STRUCTURES X STRUCTURES ] ← FUNCTIONS
Examples:1> (SET REFLECT-TEST
(LAMBDA REFLECT [ARGS ENV CONT]
(BLOCK (SET STASH ARGS) (CONT ’’OK))))
=> ’OK
1> (REFLECT-TEST + (+ 2 2))
=> ’OK
1> STASH
=> ’[+ (+ 2 2)]
1> (REFLECT-TEST . XXX)
=> ’OK
1> STASH
=> ’XXX
Semantics:S(E0("REFLECT),E,F,C) = l ...
———————————————————
(REFLECT! DEF-ENV PAT BODY)
REFLECT! is very similar to REFLECT except that the arguments to the reflective procedure are normalised before being matched against the pattern.
Properties:Cons.
F-Type:[ RAILS X STRUCTURES X STRUCTURES ] ← FUNCTIONS
Examples:1> (SET REFLECT!-TEST
(LAMBDA REFLECT! [ARGS ENV CONT]
(BLOCK (SET STASH ARGS) (CONT ’’OK))))
=> ’OK
1> (REFLECT!-TEST + (+ 2 2))
=> ’OK
1> STASH
=> ’[{simple + closure} 4]
1> (REFLECT!-TEST . 100)
=> ’OK
1> STASH
=> ’100
Semantics:S(E0("REFLECT!),E,F,C) = l ...
———————————————————
(E-REFLECT DEF-ENV PAT BODY)
When the arguments to the REFLECT! procedure are designated by a rail it behaved exactly as if it had been a REFLECT procedure; otherwise, treat it like a REFLECT!. As examples, AND, OR, and IF could have been defined as E-REFLECT procedures.
Properties:Cons.
F-Type:[ RAILS X STRUCTURES X STRUCTURES ] ← FUNCTIONS
Examples:1> (SET E-REFLECT-TEST
(LAMBDA E-REFLECT [ARGS ENV CONT]
(BLOCK (SET STASH ARGS) (CONT ’’OK))))
=> ’OK
1> (E-REFLECT-TEST + (+ 2 2))
=> ’OK
1> STASH
=> ’[+ (+ 2 2)]
1> (E-REFLECT-TEST . +)
=> ’OK
1> STASH
=> ’{simple + closure}
Semantics:S(E0("E-REFLECT),E,F,C) = l ...
———————————————————
(MACRO DEF-ENV PAT BODY)
When a procedure call (FOO . ARGS) is normalised (at level N) 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.
Properties:Protected; kernel; cons..
F-Type:[ RAILS X STRUCTURES X STRUCTURES ] ← FUNCTIONS
Examples:1> (SET MACRO-TEST
(LAMBDA MACRO ARGS
(BLOCK (SET STASH ARGS) ARGS)))
=> ’OK
1> (MACRO-TEST + (+ 2 2))
=> [{simple + closure} 4]
1> STASH
=> ’[+ (+ 2 2)]
1> (MACRO-TEST . +)
=> {simple + closure}
1> STASH
=> ’+
Semantics:S(E0("MACRO),E,F,C) = l ...
———————————————————
(E-MACRO DEF-ENV PAT BODY)
E-MACRO is to MACRO as E-REFLECT is to REFLECT.
Properties:Cons.
F-Type:[ RAILS X STRUCTURES X STRUCTURES ] ← FUNCTIONS
Examples:1> (SET E-MACRO-TEST
(LAMBDA MACRO ARGS
(BLOCK (SET STASH ARGS) ARGS)))
=> ’OK
1> (E-MACRO-TEST + (+ 2 2))
=> [{simple + closure} 4]
1> STASH
=> ’[+ (+ 2 2)]
1> (E-MACRO-TEST . +)
=> {simple + closure}
1> STASH
=> ’{simple + closure}
Semantics:S(E0("E-MACRO),E,F,C) = l ...
———————————————————
(REBIND VAR BIND ENV)
Modifies the environment designated by ENV to contain a binding of the internal structure designated by VAR to the internal structure designated by BIND. If the structure designated by VAR is already bound, that binding will be modified in place; if not, a new binding of the structure designated by VAR to the structure designated by BIND will be added to the foot of the environment designated by ENV. Environments generated by the 3-LISP processor consist only of atoms bound to normal-form structures, so that VAR should designate an atom and BIND a normal-form internal structure if ENV is intended to continue to designate a well-formed 3-LISP environment. Returns ’OK.
Properties:Protected; cons; smash.
F-Type:[ STRUCTURES X STRUCTURES X SEQUENCES ] ← ATOMS
Examples:(LET [[ENV [[’X ’1] [’Y ’2]]]]
(BLOCK (REBIND ’Y ↑(+ 2 3) ENV)
(REBIND ’Z ’$T ENV)
ENV))g[[’X ’1] [’Y ’5] [’Z ’$T]]
Semantics:S(E0("REBIND),E,F,C) = l ...
———————————————————
(SET VAR BINDING)
SET uses REBIND to alter 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 ’OK.
Properties:Protected; smash-env; abnormal.
Y-Type:[ ATOMS X STRUCTUURES ] ← HANDLES
Examples:1> (SET X (+ 2 2))
=> ’OK
1> X
=> 4
1> (SET X (+ X X))
=> ’OK
1> X
=> 8
Semantics:S(E0("SET),E,F,C) = l ...
———————————————————
(SETREF VAR BINDING)
SETREF is a variant of SET in which both VAR and BINDING are normalised. Returns ’OK.
Properties:Smash-env.
Y-Type:[ HANDLES X STRUCTUURES ] ← HANDLES
Examples:1> (SET X ’Y)
=> ’OK
1> (SETREF X (* 2 2))
=> ’OK
1> Y
=> 4
Semantics:S(E0("SETREF),E,F,C) = l ...
———————————————————
(BINDING VAR ENV)
Designates the binding of the internal structure designated by VAR in the environment designated by ENV. The 3-LISP processor will on its own only establish normal-form bindings for atoms, so VAR should designate an atom unless the user provides his or her own environment structure (in which case BINDING can be used as a 3-LISP analog of LISP 1.5’s ASSOC).
Properties:Protected; kernel.
F-Type:[ STRUCTURES X SEQUENCES ] ← STRUCTURES
Examples:(BINDING ’Y [[’X ’1] [’Y ’2] [’Z ’3]])g’2
(BINDING ’NORMALISE GLOBAL)g’{simple NORMALISE closure}
(LET [[X (+ 1 2)]]
((LAMBDA REFLECT [ARGS ENV CONT]
(CONT (BINDING ’X ENV)))))g3
Semantics:S(E0("BINDING),E,F,C) = l ...
———————————————————
(BIND PATTERN ARGS ENV)
Designates an environment obtained by augmenting the environment designated by ENV with the variable bindings that result from the matching of the pattern structure designated by PATTERN against the argument structure designated by ARGS. A pattern consisting of a single atom will match any argument structure directly; this results in the atom becoming bound to the entire argument structure. This basic matching process is extended to rail patterns in the usual way: pattern and argument rails must match on an element by element basis.
Properties:Protected; kernel; cons.
F-Type:[ STRUCTURES X STRUCTURES X SEQUENCES ] ← SEQUENCES
Examples:(BIND ’X ’2 [[’Y ’1]]) g[[’X ’2] [’Y ’1]]
(BIND ’[X] ’[2] [[’Y ’1]])g[[’X ’2] [’Y ’1]]
(BIND ’[X] ’’[2] [[’Y ’1]])g[[’X ’’2] [’Y ’1]]
(BIND ’[X Z] ’[2 3] [[’Y ’1]])g[[’X ’2] [’Z ’3] [’Y ’1]]
(BIND ’[X Y] ’[[2] 3] [[’Y ’1]])g[[’X ’[2]] [’Y ’3] [’Y ’1]]
(BIND ’[X [Y]] ’[2 [3]] [[’Y ’1]])g[[’X ’2] [’Y ’3] [’Y ’1]]
(BIND ’[X] ’2 [[’Y ’1]])g{ERROR}
(BIND ’[X] ’’’[2] [[’Y ’1]])g{ERROR}
(BIND ’(A . B) ’(1 . 2) [[’Y ’1]])g{ERROR}
Semantics:S(E0("BIND),E,F,C) = l ...
———————————————————
(LET [[P1 E1] ... [Pk Ek]] BODY)
Designates (in an environment ENV1) the designation that BODY has in an environment ENV2 which is like ENV1 except extended by matching the patterns Pi to the results of normalising the expressions Ei in environment ENV1. In other words all of the Ei are normalised in the same environment. It can be determined (because of the way in which rails are normalised) that the Ei will be normalised sequentially, but it is considered bad programming practice to depend on this fact (only BLOCK should be used for explicit sequential processing).
Properties:Protected; kernel; env; abnormal.
Macro:(LET [[P1 E1] ... [Pk Ek]] BODY) W>
((LAMBDA SIMPLE [P1 ... Pk] BODY) E1 ... Ek)
Examples:(LET [[X 3] [Y 4]] (+ X Y))g7
(LET [[[A B] (REST [1 1 2])]] (= A B))g$F
(LET [[X 3]]
(LET [[X 4] [Y X]] (+ X Y)))g7
Semantics:S(E0("LET),E,F,C) = l ...
———————————————————
(LETSEQ [[P1 E1] ... [Pk Ek]] BODY)
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]] BODY) W>
(LET [[P1 E1]]
(LETSEQ [P2 E2] ... [Pk Ek]] BODY))
Examples:(LET [[X 3]]
(LETSEQ [[X 4] [Y X]] (+ X Y)))g8
Semantics:S(E0("LETSEQ),E,F,C) = l ...
———————————————————
(LABELS [[P1 E1] ... [Pk Ek]] BODY)
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 matching all of the patterns Pi against the normalisations of their Ei. (In the near future, LABELS will be renamed LETREC.)
Properties:Env; abnormal.
Macro:(LABELS [[P1 E1][P2 E2] ... [Pk Ek]] BODY) W>
(LET [[P1 ’HUCAIRZ][P2 ’HUCAIRZ] ... [Pk ’HUCAIRZ]]
(BLOCK (SET P1 E1)
(SET P2 E2)
...
(SET Pk Ek)
BODY))
Examples:(LABELS [[EVEN (LAMBDA SIMPLE [N]
(IF (= N 0) $T (ODD (1- N))))]
[ODD (LAMBDA SIMPLE [N]
(IF (= N 0) $F (EVEN (1- N))))]]
(SCONS (EVEN 2) (ODD 2)))g[$T $F]
Semantics:S(E0("LABELS),E,F,C) = l ...