Up | Next | Prev | PrevTail | Tail |
The let
statement offers an alternative syntax and semantics for procedure
definition.
In place of
procedure abc(x,y,z); <procedure body>;
one can write
for all x,y,z let abc(x,y,z) => <procedure body>;
There are several differences to note.
If the procedure body contains an assignment to one of the formal parameters, e.g.
x := 123;
in the procedure
case it is a variable holding a copy of the first actual argument that is
changed. The actual argument is not changed.
In the let
case, the actual argument is changed. Thus, if abc
is defined using let
, and
abc(u,v,w)
is evaluated, the value of u
changes to 123. That is, the let
form of
definition allows the user to bypass the protections that are enforced by the call by value
conventions of standard procedure
definitions.
Example: We take our earlier factorial
procedure and write it as a let
statement.
for all n let factorial n => begin scalar m,s; m:=1; s:=n; l1: if s=0 then return m; m:=m*s; s:=s-1; go to l1 end;
The reader will notice that we introduced a new local variable, s
, and set it equal to n
.
The original form of the procedure contained the statement n:=n-1;
. If the user asked
for the value of factorial(5)
then n
would correspond to, not just have the
value of, 5, and REDUCE would object to trying to execute the statement 5 :=
\(5-1\).
If pqr
is a procedure with no parameters,
procedure pqr; <procedure body>;
it can be written as a let
statement quite simply:
let pqr => <procedure body>;
To call procedure pqr
, if defined in the latter form, the empty parentheses would not be
used: use pqr
not pqr()
where a call on the procedure is needed.
The two notations for a procedure with no arguments can be combined. pqr
can be
defined in the standard procedure
form. Then a let
statement
let pqr => pqr();
would allow a user to use pqr
instead of pqr()
in calling the procedure.
A feature available with let
-defined procedures and not with procedures defined in the
standard way is the possibility of defining partial functions.
for all x such that numberp x let uvw(x) => <procedure body>;
Now uvw
of an integer would be calculated as prescribed by the procedure body,
while uvw
of a general argument, such as z
or p+q
(assuming these evaluate
to themselves) would simply stay uvw(z)
or uvw(p+q)
as the case may
be.
Up | Next | Prev | PrevTail | Front |