Subject: Re: using DEFINE to break complex function into simpler parts
From: rpw3@rigden.engr.sgi.com (Rob Warnock)
Date: 1997/01/23
Newsgroups: comp.lang.scheme
Message-ID: <5c7crt$3hg@tokyo.engr.sgi.com>

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