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>
> (let ((a 3)) (+ a 1))
4
> (let ((a 2)
(b 3)
(c 0))
(setq c (+ a b))
c)
5
> (setq c 4)
4 ;and a warning from CMUCL, ignore it
> (let ((c 5)) c)
5
> 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>
> (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
#<C::REF #x9009B15 LEAF= #<C::GLOBAL-VAR #x9009AD5 NAME= X KIND=
:GLOBAL>>
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>
> (setq x 7)
7 ;again a warning in CMUCL:
Warning: Declaring X special.
;x is automaticly declared special
> (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>
> (setq x 7)
7
> (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>
|