John L. Stein <stein@seas.ucla.edu> wrote [well, cleaned up]:
+---------------
| The following works.
|
| STk> (define (bite!)
| (let ((n 2))
| (lambda () (write n))))
|
| But the following doesn't work.
|
| STk> (define (bite!)
| (let ((n 2))
| (bit!)))
| STk> (define (bit!)
| (lambda () (write n)))
| STk> ((bite!))
| *** Error:
| unbound variable: n
| STk>
|
| Whats the difference ?
+---------------
Two words: Lexical scope.
[Both Scheme & CL (ignoring "special" variables) have lexical scope,
as opposed to many/most earlier Lisps which had dynamic scope...]
Try writing your second example in C [also lexically scoped], and
you will have exactly the same problem (I used "static" so the value
of "n" will hang around between calls, which is as close as C gets
to closures):
% cat foo.c
void bite_bang() {
static int n = 2;
bit_bang();
}
void bit_bang() {
printf("n = %d\n", n);
}
% cc -c foo.c
cfe: Error: foo.c, line 6: 'n' undefined; reoccurrences
will not be reported.
printf("n = %d\n", n);
-----------------------^
%
+---------------
| Does'nt lambda inherit n = 2 from its parent environment
| when ((bite!)) is called?
+---------------
But "n" is not *in* bit!'s environment! (It's in bite!'s environment,
but that's a whole other story.)
-Rob
-----
Rob Warnock, 7L-551 rpw3@sgi.com
Silicon Graphics, Inc. http://reality.sgi.com/rpw3/
2011 N. Shoreline Blvd. Phone: 415-933-1673 FAX: 415-933-0979
Mountain View, CA 94043 PP-ASEL-IA