File: LISP-tutorial-11.html

package info (click to toggle)
cmucl 20c-2
  • links: PTS
  • area: main
  • in suites: wheezy
  • size: 42,524 kB
  • sloc: lisp: 358,331; ansic: 28,385; asm: 3,777; sh: 1,236; makefile: 366; csh: 31
file content (153 lines) | stat: -rw-r--r-- 3,440 bytes parent folder | download | duplicates (12)
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
144
145
146
147
148
149
150
151
152
153
<HTML>
<HEAD>
<TITLE>Common LISP Hints: Binding</TITLE>
</HEAD>
<BODY>
<A HREF="LISP-tutorial-10.html"><IMG SRC="prev.gif" ALT="Previous"></A>
<A HREF="LISP-tutorial-12.html"><IMG SRC="next.gif" ALT="Next"></A>
<A HREF="LISP-tutorial.html#toc11"><IMG SRC="toc.gif" ALT="Contents"></A>
<HR>
<H2><A NAME="s11">11. Binding</A></H2>

<P>Binding is lexically scoped assignment. It happens to the variables in
a function's parameter list whenever the function is called: the formal
parameters are bound to the actual parameters for the duration of the
function call. You can bind variables anywhere in a program with the
let special form, which looks like this:</P>
<P>
<BLOCKQUOTE><CODE>
<PRE>
(let ((var1 val1)
      (var2 val2)
      ...
     )
    body)
</PRE>
</CODE></BLOCKQUOTE>
</P>
<P>(It's considered bad style to leave a single ``)'' on a line)</P>
<P>Let binds <CODE>var1</CODE> to <CODE>val1</CODE>, <CODE>var2</CODE> to <CODE>val2</CODE>, and so
forth; then it executes 
the statements in its body. The body of a let follows exactly the same
rules that a function body does. Some examples:</P>
<P>
<BLOCKQUOTE><CODE>
<PRE>
&gt; (let ((a 3)) (+ a 1))
4
&gt; (let ((a 2) 
        (b 3)
        (c 0))
    (setq c (+ a b))
    c)
5
&gt; (setq c 4)
4                     ;and a warning from CMUCL, ignore it    
&gt; (let ((c 5)) c)
5
&gt; c
4
</PRE>
</CODE></BLOCKQUOTE>
</P>
<P>Instead of <CODE>(let ((a nil) (b nil)) ...)</CODE>, you can write <CODE>(let (a b) ...)</CODE>.</P>
<P>The <CODE>val1</CODE>, <CODE>val2</CODE>, etc. inside a let cannot reference the
variables <CODE>var1</CODE>, 
<CODE>var2</CODE>, etc. that the let is binding. For example,</P>
<P>
<BLOCKQUOTE><CODE>
<PRE>
&gt; (let ((x 1)
        (y (+ x 1)))
    y)
Error: Attempt to take the value of the unbound symbol X
                      ;in CMUCL:

In: LET ((X 1) (Y (+ X 1)))
  (LET ((X 1) (Y #))
    Y)
Warning: Variable X defined but never used.


Warning: This variable is undefined:
  X

Error in KERNEL::UNBOUND-SYMBOL-ERROR-HANDLER:  the variable X is
unbound.

Restarts:
  0: [ABORT] Return to Top-Level.

Debug  (type H for help)

(EVAL::LEAF-VALUE
 #&lt;C::REF #x9009B15  LEAF= #&lt;C::GLOBAL-VAR #x9009AD5  NAME= X  KIND=
 :GLOBAL&gt;&gt;
 0
 #())
0]
</PRE>
</CODE></BLOCKQUOTE>
</P>
<P>If the symbol <CODE>x</CODE> already has a global value, stranger happenings will
result:</P>
<P>
<BLOCKQUOTE><CODE>
<PRE>
&gt; (setq x 7)
7                     ;again a warning in CMUCL:
Warning:  Declaring X special.
                      ;x is automaticly declared special
&gt; (let ((x 1)
        (y (+ x 1)))
    y
  )
8
</PRE>
</CODE></BLOCKQUOTE>
</P>
<P>The <CODE>let*</CODE> special form is just like <CODE>let</CODE> except that it allows
values to 
reference variables defined earlier in the <CODE>let*</CODE>. For example,</P>
<P>
<BLOCKQUOTE><CODE>
<PRE>
&gt; (setq x 7)
7
&gt; (let* ((x 1)
         (y (+ x 1)))
    y
  )
2
</PRE>
</CODE></BLOCKQUOTE>
</P>
<P>The form</P>
<P>
<BLOCKQUOTE><CODE>
<PRE>
(let* ((x a)
       (y b))
       ...
) 
</PRE>
</CODE></BLOCKQUOTE>
</P>
<P>is equivalent to</P>
<P>
<BLOCKQUOTE><CODE>
<PRE>
(let ((x a))
     (let ((y b))
          ...
) )
</PRE>
</CODE></BLOCKQUOTE>
</P>

<HR>
<A HREF="LISP-tutorial-10.html"><IMG SRC="prev.gif" ALT="Previous"></A>
<A HREF="LISP-tutorial-12.html"><IMG SRC="next.gif" ALT="Next"></A>
<A HREF="LISP-tutorial.html#toc11"><IMG SRC="toc.gif" ALT="Contents"></A>
</BODY>
</HTML>