Path: utzoo!utgpu!water!watmath!clyde!att!osu-cis!tut.cis.ohio-state.edu!bloom-beacon!KLEPH.AI.MIT.EDU!cph From: cph@KLEPH.AI.MIT.EDU (Chris Hanson) Newsgroups: comp.lang.scheme Subject: Macros; lexcial scope Message-ID: <8805261727.AA06410@kleph> Date: 26 May 88 17:27:07 GMT References: <8805251659.AA00682@tub.UUCP> Sender: daemon@bloom-beacon.MIT.EDU Reply-To: cph@zurich.ai.mit.edu Organization: The Internet Lines: 63 Date: Wed, 25 May 88 18:59:30 +0200 From: Oliver Laumann Consider the following example: (define x 1) (define-macro (m) x) (let ((x 2)) (m)) in both Common Lisp (using a different syntax, of course) and C-Scheme, (m) returns 1 in the example above. You have an old version of C-Scheme. The current version (release 6 and later) gives an "unbound variable X" error while evaluating the last expression. Now consider a slighly more complex example: (define x 1) (let ((x 2)) (define-macro (m) x) (let ((x 3)) (m))) In both Common Lisp and C-Scheme, this evaluates to 1. Again, this produces an "unbound variable X" error in the current release. As one of several people who has thought about the issues you raise, I'll offer the following: 1. The semantics of special forms like `define-macro' is confusing. The naive interpretation of the meaning requires that a macro created this way should be closed in the environment in which it lexically appears. Unfortunately, that environment usually does not exist until run time, while for obvious reasons it is desirable that macros be closed at compile time. 2. C-Scheme has "solved" this problem by forcing all such macros to be closed in the global environment (actually, in a distinct child of the global environment). This alternate environment is guaranteed to exist at compile time, and under normal circumstances your other definitions won't interact with it. Thus, this explains the "unbound variable" errors. I say "solved" above because, rather than providing an acceptable solution, all we've really done is try to make it obvious when the user is confused about the closing environment. 3. My personal conclusion is that `define-macro' is a bad idea. I rarely, if ever, use it. C-Scheme provides facilities for explicitly constructing syntax tables (see the file "runtime/syntax.scm", procedures `make-syntax-table' and `syntax-table-define', and the special forms `macro' and `using-syntax') which do not have this problem. Using these facilities, the macros are closed in the environment in which they are loaded. They also appear in a different file from their references, thus reducing the confusion. 4. The R*RS committee is in the process of generating a "standard" macro facility. Keep tuned for more news.