File: LET.html

package info (click to toggle)
acl2 3.1-1
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 36,712 kB
  • ctags: 38,396
  • sloc: lisp: 464,023; makefile: 5,470; sh: 86; csh: 47; cpp: 25; ansic: 22
file content (143 lines) | stat: -rw-r--r-- 7,039 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
<html>
<head><title>LET.html  --  ACL2 Version 3.1</title></head>
<body text=#000000 bgcolor="#FFFFFF">
<h2>LET</h2>binding of lexically scoped (local) variables
<pre>Major Section:  <a href="PROGRAMMING.html">PROGRAMMING</a>
</pre><p>


<pre>
Example LET Form:
(let ((x (* x x))
      (y (* 2 x)))
 (list x y))
</pre>

If the form above is executed in an environment in which <code>x</code> has the
value <code>-2</code>, then the result is <code>'(4 -4)</code>.
<p>
<code>Let</code> expressions bind variables so that their ``local'' values, the
values they have when the ``body'' of the <code>let</code> is evaluated, are
possibly different than their ``global'' values, the values they
have in the context in which the <code>let</code> expression appears.  In the <code>let</code>
expression above, the local variables bound by the <code>let</code> are <code>x</code> and <code>y</code>.
They are locally bound to the values delivered by the two forms
<code>(* x x)</code> and <code>(* 2 x)</code>, respectively, that appear in the
``bindings'' of the <code>let</code>.  The body of the <code>let</code> is <code>(list x y)</code>.<p>

Suppose that the <code>let</code> expression above occurs in a context in which <code>x</code>
has the value <code>-2</code>.  (The global value of <code>y</code> is irrelevant to this
example.)  For example, one might imagine that the <code>let</code> form above
occurs as the body of some function, <code>fn</code>, with the formal parameter <code>x</code>
and we are evaluating <code>(fn -2)</code>.<p>

To evaluate the <code>let</code> above in a context in which <code>x</code> is <code>-2</code>, we first
evaluate the two forms specifying the local values of the variables.
Thus, <code>(* x x)</code> is evaluated and produces <code>4</code> (because <code>x</code> is <code>-2</code>) and
<code>(* 2 x)</code> is evaluated and produces <code>-4</code> (because <code>x</code> is <code>-2</code>).
Then <code>x</code> and <code>y</code> are bound to these values and the body of the <code>let</code>
is evaluated.  Thus, when the body, <code>(list x y)</code> is evaluated, <code>x</code>
is <code>4</code> and <code>y</code> is <code>-4</code>.  Thus, the body produces <code>'(4 -4)</code>.<p>

Note that the binding of <code>y</code>, which is written after the binding of <code>x</code>
and which mentions <code>x</code>, nevertheless uses the global value of <code>x</code>, not
the new local value.  That is, the local variables of the <code>let</code> are
bound ``in parallel'' rather than ``sequentially.'' In contrast, if
the

<pre>
Example LET* Form:
(let* ((x (* x x))
       (y (* 2 x)))
 (list x y))
</pre>

is evaluated when the global value of <code>x</code> is <code>-2</code>, then the result is
<code>'(4 8)</code>, because the local value of <code>y</code> is computed after <code>x</code> has been
bound to <code>4</code>.  <code><a href="LET_star_.html">Let*</a></code> binds its local variables ``sequentially.''

<pre>
General LET Forms:
(let ((var1 term1) ... (varn termn)) body) 
and
(let ((var1 term1) ... (varn termn))
 (declare ...) ... (declare ...)
 body)
</pre>

where the <code>vari</code> are distinct variables, the <code>termi</code> are terms
involving only variables bound in the environment containing the
<code>let</code>, and <code>body</code> is a term involving only the <code>vari</code> plus the variables
bound in the environment containing the <code>let</code>.  Each <code>vari</code> must be used
in <code>body</code> or else <a href="DECLARE.html">declare</a>d ignored.<p>

A <code>let</code> form is evaluated by first evaluating each of the <code>termi</code>,
obtaining for each a <code>vali</code>.  Then, each <code>vari</code> is bound to the
corresponding <code>vali</code> and <code>body</code> is evaluated.<p>

Actually, <code>let</code> forms are just abbreviations for certain uses of
<code>lambda</code> notation.  In particular

<pre>
(let ((var1 term1) ... (varn termn)) (declare ...) body)
</pre>

is equivalent to

<pre>
((lambda (var1 ... varn)
   (declare ...)
   body)
 term1 ... termn).
</pre>

<code><a href="LET_star_.html">Let*</a></code> forms are used when it is desired to bind the <code>vari</code>
sequentially, i.e., when the local values of preceding <code>varj</code> are to
be used in the computation of the local value for <code>vari</code>.

<pre>
General LET* Forms:
(let* ((var1 term1) ... (varn termn)) body) 
and
(let* ((var1 term1) ... (varn termn))
 (declare (ignore x1 ... xm))
 body) 
</pre>

where the <code>vari</code> are variables (not necessarily distinct), the
<code>termi</code> are terms involving only variables bound in the environment
containing the <code><a href="LET_star_.html">let*</a></code> and those <code>varj</code> such that <code>j&lt;i</code>, and <code>body</code> is a
term involving only the <code>vari</code> plus the variables bound in the
environment containing the <code><a href="LET_star_.html">let*</a></code>.  Each <code>vari</code> must be used either in
some subsequent <code>termj</code> or in <code>body</code>, except that in the second form
above we make an exception when <code>vari</code> is among the <code>xk</code>, in which case
<code>vari</code> must not be thus used.  Note that <code><a href="LET_star_.html">let*</a></code> does not permit the
inclusion of any <code><a href="DECLARE.html">declare</a></code> forms other than one as shown above.  In the
second general form above, every <code>xk</code> must be among the <code>vari</code>, and
furthermore, <code>xk</code> may not equal <code>vari</code> and <code>varj</code> for distinct <code>i</code>, <code>j</code>.<p>

The first <code><a href="LET_star_.html">let*</a></code> above is equivalent to

<pre>
(let ((var1 term1))
 ...
 (let ((varn termn)) body)...)
</pre>

Thus, the <code>termi</code> are evaluated successively and after each
evaluation the corresponding <code>vali</code> is bound to the value of <code>termi</code>.
The second <code><a href="LET_star_.html">let*</a></code> is similarly expanded, except that each for each
<code>vari</code> that is among the <code>(x1 ... xm)</code>, the form <code>(declare (ignore vari))</code>
is inserted immediately after <code>(vari termi)</code>.<p>

Each <code>(vari termi)</code> pair in a <code>let</code> or <code><a href="LET_star_.html">let*</a></code> form is called a ``binding''
of <code>vari</code> and the <code>vari</code> are called the ``local variables'' of the <code>let</code>
or <code><a href="LET_star_.html">let*</a></code>.  The common use of <code>let</code> and <code><a href="LET_star_.html">let*</a></code> is to save the values of
certain expressions (the <code>termi</code>) so that they may be referenced
several times in the body without suggesting their recomputation.<p>

<code>Let</code> is part of Common Lisp.  See any Common Lisp documentation
for more information.
<br><br><br><a href="acl2-doc.html"><img src="llogo.gif"></a> <a href="acl2-doc-index.html"><img src="index.gif"></a>
</body>
</html>