mirror of
https://github.com/PDP-10/its.git
synced 2026-01-20 09:55:52 +00:00
144 lines
5.3 KiB
Plaintext
Executable File
144 lines
5.3 KiB
Plaintext
Executable File
.comment -*- Mode:TEXT; -*-
|
|
.document LAMBDA - Description of the special form LAMBDA.
|
|
.tag LAMBDA
|
|
Lesson LAMBDA, Version 3 Kent M. Pitman, 1/22/80
|
|
revised by Victoria Pigman, 9/1/82
|
|
|
|
LAMBDA is not a function. Lists of a certain form which begin with the atom
|
|
LAMBDA are specially recognized by Lisp to describe functional operations.
|
|
|
|
For example, suppose I wanted to describe a function which operated on two
|
|
objects and found the sum of their squares. I could describe such a function
|
|
in Lisp as follows...
|
|
|
|
(LAMBDA (OBJECT1 OBJECT2) ; This is a list of the objects
|
|
; we are working with...
|
|
|
|
(+ (* OBJECT1 OBJECT1) ; This is an operation to do
|
|
(* OBJECT2 OBJECT2)) ; on the object.
|
|
)
|
|
|
|
The general form of a LAMBDA expression is:
|
|
|
|
(LAMBDA <bvl> <form1> <form2> ... <formN>)
|
|
|
|
where <bvl> means "bound variable list". This is a list of the names which
|
|
you wish to use locally to refer to the objects to which the function will
|
|
be applied. These values to which the function is being applied are called
|
|
the `actual parameters' or `actual arguments' or sometimes just `actuals';
|
|
the names which you are assigning to them in the bound variable list of the
|
|
formal lambda definition are called `formal parameters' or `formal arguments'
|
|
or (you guessed it) just `formals.'
|
|
|
|
<form1> ... <formN> are Lisp expressions which will be evaluated from left to
|
|
right, returning the value of the last form.
|
|
|
|
Be careful, because if you just type (LAMBDA (X Y) (* X Y)) into Lisp you'll
|
|
get an error. Lisp will complain that LAMBDA is not a function, since when it
|
|
sees a list it looks at the CAR for what to do. Lisp only understands lists
|
|
with LAMBDA in the CAR when it wants to apply the list. Just saying
|
|
|
|
(LAMBDA (VALUE1 VALUE2) (PLUS VALUE1 VALUE2))
|
|
|
|
is like saying
|
|
|
|
PLUS
|
|
|
|
When found in the CAR of a list, they both have special meaning, i.e. they
|
|
designate a functional operation, but on their own, they are meaningless.
|
|
|
|
Try typing these two and see what happens (expect an error ... you will be
|
|
asked if you want help with the type of error you got. Look if it interests
|
|
you, but then come back to me.)
|
|
.try
|
|
Functional operators must be applied. Since Lisp applies the CAR of a form to
|
|
its CDR, we can use LAMBDA in the same way as you would use any function. Since
|
|
you would say
|
|
|
|
(PLUS 7 B)
|
|
|
|
(assuming B has a value) you must also put LAMBDA expressions in the CAR of the
|
|
list, like so:
|
|
|
|
((LAMBDA (VALUE1 VALUE2)
|
|
(PLUS (* VALUE1 VALUE1)
|
|
(* VALUE2 VALUE2)))
|
|
7 B)
|
|
.eval
|
|
(progn
|
|
(format t "~&")
|
|
(cond ((not (boundp 'B))
|
|
(setq b 3)
|
|
(format t "(B has been given a value of 3 for your convenience)"))
|
|
((not (numberp B))
|
|
(format t "You have assigned a non-numeric value to B, ~
|
|
so you should pick another value to use instead."))))
|
|
.try
|
|
A form which contains a LAMBDA expression (which we sometimes call a LAMBDA
|
|
operator) applied to some arguments is called a LAMBDA combination.
|
|
|
|
LAMBDA combinations have the general form:
|
|
|
|
((LAMBDA <bound-variable-list> <form1> <form2> ...)
|
|
<arg1> <arg2> ... )
|
|
|
|
where the number of <arg>'s must be equal to the number of elements in the
|
|
bound variable list.
|
|
|
|
When a LAMBDA combination is executed, the following steps are taken in this
|
|
order:
|
|
|
|
(1) The actual args, <arg1> ... <argN> in the above example,
|
|
are evaluated in order from LEFT to RIGHT.
|
|
|
|
(2) When all values have been computed, the old values of all
|
|
the symbols in the bound variable list (if they had old
|
|
values) are saved in a place where they can be gotten back
|
|
later. Then the symbols are assigned the new local values
|
|
which were gotten by evaluating the actual arguments. This
|
|
process is called binding (which is why the list of local
|
|
variables is called a bound variable list).
|
|
|
|
(3) The body of the LAMBDA expression is executed in a context
|
|
in which the local variables are bound to these values.
|
|
|
|
(4) The value returned by the last expression in a LAMBDA
|
|
will be returned from a LAMBDA.
|
|
|
|
(5) Unbeknownst to you (practically), Lisp goes and restores the
|
|
old values of the variables in the bound variable list so
|
|
that if any other functions had been using them as storage
|
|
places, they won't be confused by having called your
|
|
function.
|
|
|
|
Try some of these examples:
|
|
|
|
((LAMBDA (X) (+ (* X X) (* 2 X) 1)) 3)
|
|
|
|
((LAMBDA (X) (^ (+ X 1) 2)) 3) ; Does same thing as the one above it
|
|
|
|
((LAMBDA (A B C)
|
|
(PRINT (LIST 'GOT-THE-ARGUMENTS A B C)) ; Print out info
|
|
(+ A B C)) ; Return their sum
|
|
3 4 5) ; Actual arguments to the function description
|
|
.try
|
|
LAMBDA expressions do not need to have any variables in their bound variable
|
|
list. If they have no variables, they need have no arguments ... Here is an
|
|
example ...
|
|
|
|
((LAMBDA () T))
|
|
|
|
These may seem useless, but they illustrate an important concept. A LAMBDA
|
|
expression is a functional description, and we can describe any kind of
|
|
function, including one with no arguments. LAMBDA's are often used when we
|
|
wish to build a function to pass to another function which will then use it
|
|
for its own purposes; in such a circumstance a function of no arguments can be
|
|
useful.
|
|
|
|
In fact, people rarely use un-named LAMBDA's at all. If you are going to do
|
|
an operation more than once, it makes sense to assign it a name and call it by
|
|
name. What you want to do now is proceed to (LESSON DEFUN) where you can learn
|
|
all about naming your LAMBDA's for later use.
|
|
.next DEFUN
|
|
|