From: Conrad Barski
Subject: symbol-macrolet  errata in CLISP vs CMUCL
Date: 
Message-ID: <a4af10cf.0312141803.757c027e@posting.google.com>
In CLISP or CMUCL, if you run the following code:

[1]> (symbol-macrolet ((a 5)) (symbol-macrolet ((b a)) b))

(CMUCL and CLISP) ==> 5

This is the expected behavior. Naturally, one would expect to get the
same result if one wraps this code in a function:

[1]> (defun foo () (symbol-macrolet ((a 5)) (symbol-macrolet ((b a))
b)))

[2]> (foo)

(CMUCL) ==> 5
(CLISP) ==> *** EVAL: variable A has no value 

Having nested symbol-macrolets would seem to be a pretty basic
feature... Why doesn't it seem to work? Is there a known CLISP errata
for this?

-Thanks

From: Kaz Kylheku
Subject: Re: symbol-macrolet  errata in CLISP vs CMUCL
Date: 
Message-ID: <cf333042.0312151133.396f0a5@posting.google.com>
·····················@yahoo.com (Conrad Barski) wrote in message news:<····························@posting.google.com>...
> In CLISP or CMUCL, if you run the following code:
> 
> [1]> (symbol-macrolet ((a 5)) (symbol-macrolet ((b a)) b))
> 
> (CMUCL and CLISP) ==> 5
> 
> This is the expected behavior. Naturally, one would expect to get the
> same result if one wraps this code in a function:
> 
> [1]> (defun foo () (symbol-macrolet ((a 5)) (symbol-macrolet ((b a))
> b)))
>
> [2]> (foo)
> 
> (CMUCL) ==> 5
> (CLISP) ==> *** EVAL: variable A has no value 
> 
> Having nested symbol-macrolets would seem to be a pretty basic
> feature... Why doesn't it seem to work? Is there a known CLISP errata
> for this?

The HyperSpec says ``Each reference to symbol as a variable within the
lexical scope of symbol-macrolet is expanded by the normal macro
expansion process; see Section 3.1.2.1.1 (Symbols as Forms). The
expansion of a symbol macro is subject to further macro expansion in
the same lexical environment as the symbol macro invocation, exactly
analogous to normal macros.''

The problem here, firstly, is that in the inner SYMBOL-MACROLET, the
symbol A is not being used as a variable. That is to say:

   (symbol-macrolet ((b a)) ...) ;; A is not a form here!

So the expansion is not allowed to take place here; if B is to produce
5, it has to be done by a repeated expansion through A. The second
sentence above does seem to require this. The invocation B should
expand to A, which should be further macroexpanded in the same lexical
environment, where A is indeed known to be a symbol macro with the
expansion 5.

Moreover, CLISP does get this right when you use ordinary macros. If
we substitute MACROLET for SYMBOL-MACROLET and add a few parentheses,
it works:

   (defun foo () (macrolet ((a () 5)) (macrolet ((b () (a))) (b))))

   (foo) -> 5

(b) nicely expands to (a) which substitutes 5. So even if the spec did
not require the nesting to work, CLISP would be inconsistent in its
treatment of symbol and normal macros.

One more observation: note that CLISP also breaks it if you collapse
the nesting, namely:

   (symbol-macrolet ((a 5) (b a)) b)  => 5   ;; top level

Fails in function body. So the nesting isn't relevant to the bug; it's
just a failure to re-process the macro expansion for more expansions.

And, final observation: if you COMPILE the function, it works!

   (compile 'foo)

   (foo) => 5 ;; aha!

So there we go.
From: Bruno Haible
Subject: Re: symbol-macrolet  errata in CLISP vs CMUCL
Date: 
Message-ID: <brl0rq$ec4$1@laposte.ilog.fr>
Conrad Barski <·····················@yahoo.com> wrote:

> [2]> (foo)
>
> (CMUCL) ==> 5
> (CLISP) ==> *** EVAL: variable A has no value 

It's a bug in CLISP. Appended you find the fix. And a workaround is to
compile the function: (compile 'foo); then it works.

                       Bruno


*** init.lisp	11 Dec 2003 16:18:38 -0000	1.110
--- init.lisp	15 Dec 2003 19:04:32 -0000
***************
*** 605,615 ****
      (let (h)
        (if (and (symbolp form)
                 (symbol-macro-p (setq h (venv-assoc form *venv*))))
!         (values (sys::%record-ref h 0) t)
          (values form nil)))
      #-COMPILER
      (if (and (symbolp form) (symbol-macro-p (venv-assoc form *venv*)))
!       (values (sys::%record-ref (venv-assoc form *venv*) 0) t)
        (values form nil))
      ;; form is a CONS
      (let ((f (first form)))
--- 605,615 ----
      (let (h)
        (if (and (symbolp form)
                 (symbol-macro-p (setq h (venv-assoc form *venv*))))
!         (values (%expand-form (sys::%record-ref h 0)) t)
          (values form nil)))
      #-COMPILER
      (if (and (symbolp form) (symbol-macro-p (venv-assoc form *venv*)))
!       (values (%expand-form (sys::%record-ref (venv-assoc form *venv*) 0)) t)
        (values form nil))
      ;; form is a CONS
      (let ((f (first form)))
From: Conrad Barski
Subject: Re: symbol-macrolet  errata in CLISP vs CMUCL
Date: 
Message-ID: <a4af10cf.0312161007.54d83a6b@posting.google.com>
> It's a bug in CLISP. Appended you find the fix. And a workaround is to
> compile the function: (compile 'foo); then it works.

THANK YOU, THANK YOU, THANK YOU!

-Conrad