Subject: Re: beginner question
From: rpw3@rigden.engr.sgi.com (Rob Warnock)
Date: 1998/04/28
Newsgroups: comp.lang.lisp
Message-ID: <6i3u09$6clm@fido.asd.sgi.com>

Erik Naggum  <clerik@naggum.no> wrote:
+---------------
| | How does one avoid this when one wants normal (to a Scheme user) lexical
| | scope for a global variable?  What declaration or initial definition form
| | does one use?
| 
|   well, in sharp contrast to Scheme, we have very easy access to lexical
|   closures in Common Lisp.  e.g.,
| 
| (let ((line-counter 0))
|   (defun foo (...)
|     ... line-counter ...)
|   (defun bar (...)
|     ... line-counter ...))
| 
|   will create two functions FOO and BAR that share the lexical binding of
|   LINE-COUNTER.  in Scheme, as I'm sure you are aware, the LET-form would
|   remove the top-level-ness of the now _internal_ defining forms and just
|   return some arbitrary values instead of defining new functions.
+---------------

But that really wasn't the quesion I was asking! To rephrase it in the
context of your example, suppose when you write the code you give, there's
*already* a top-level variable named "line-counter" -- which, as several
people have answered me, is necessarily "special" (dynamic). So now instead
of getting a new lexical variable "line-counter" for your functions "foo" &
"bar" to share privately, you have perturbed the value of the global dynamic
variable "line-counter", and if either "foo" or "bar" calls a function that
uses "line-counter", unexpectedness will happen... (Won't it?)

+---------------
|   I find Common Lisp to be far superior to Scheme, which encourages
|   a proliferation of global symbols with lexical semantics as opposed to
|   carefully constrained access to shared lexical bindings, which I found
|   real cumbersome to do last time I tried it in Scheme, but I'm certainly
|   no fan of Scheme, so I might well have missed something important.
+---------------

As someone else pointed out, the way you do what you want in Scheme is:

	(define foo #f)
	(define bar #f)
	(let ((line-counter 0))
	  (set! foo (lambda (...) ...))
	  (set! bar (lambda (...) ...)))

(which is basically identical to the usual expansion of "letrec"...)

Thus, one *can* carefully control which symbols one pollutes the global
namespace with. (Of course, I concede you the point that one *needs* to
take such care, since standard Scheme only has one namespace.)


-Rob

-----
Rob Warnock, 7L-551		rpw3@sgi.com   http://reality.sgi.com/rpw3/
Silicon Graphics, Inc.		Phone: 650-933-1673 [New area code!]
2011 N. Shoreline Blvd.		FAX: 650-933-4392
Mountain View, CA  94043	PP-ASEL-IA