From: Antony Sequeira
Subject: onlisp with-gensyms and allf macro question
Date: 
Message-ID: <pxyqc.50613$Sm.7324@newssvr29.news.prodigy.com>
Hi
I am reading OnLisp trying to learn macros.
I am having trouble with the following two

;;pp. 145
;;evaluate a body with bunch of symbols in list syms set to gensyms
(defmacro with-gensyms (syms &body body)
   `(let ,(mapcar #�(lambda (s)
                      `(,s (gensym)))
                    syms)
     ,@body))

;;pp. 169
;;sets a bunch of varibales in args to the value val
(defmacro allf (val &rest args)
   (with-gensyms (gval)
     `(let ((,gval ,val))
       (setf ,@(mapcan #�(lambda (a) (list a gval))
                         args)))))

They seem to work fine in clisp (2.30)
In cmucl I am having problems trying to use allf.
I have a test file with just these two called test2.lisp
Here is what I get (i have stripped some empty lines here)
---------------------------------------------------------
CMU Common Lisp 18e, running on xxxxx
With core: /usr/lib/cmucl/lib/lisp.core
Dumped on: Thu, 2003-04-03 05:47:12-08:00 on orion
See <http://www.cons.org/cmucl/> for support information.
Loaded subsystems:
     Python 1.1, target Intel x86
     CLOS 18e (based on PCL September 16 92 PCL (f))
* (compile-file "test2.lisp")
; Python version 1.1, VM version Intel x86 on 18 MAY 04 05:58:46 pm.
; Compiling: xxxxx/test2.lisp 18 MAY 04 05:47:20 pm
; File: xxxxxx/test2.lisp
; In: DEFMACRO WITH-GENSYMS
;   (MAPCAR #<Interpreted Function # {48029741}> SYMS)
; --> LET
; ==>
;   #<Interpreted Function (LAMBDA # `#) {48029741}>
; Error: Cannot dump objects of type EVAL:INTERPRETED-FUNCTION into fasl 
files.
;
; Converted WITH-GENSYMS.
; File: /u/antony/test2.lisp
; In: DEFMACRO WITH-GENSYMS
;   `(LET (COMMON-LISP::BACKQ-COMMA #)
;      ,@BODY)
; --> LIST*
; ==>
;   BODY
; Note: Deleting unreachable code.
;   (MAPCAR #<Interpreted Function # {48029741}> SYMS)
; --> LET LET DO-ANONYMOUS BLOCK LET
; ==>
;   SYMS
; Note: Deleting unreachable code.
; Compiling DEFMACRO WITH-GENSYMS:
; File: /u/antony/test2.lisp
; In: DEFMACRO ALLF
;   (MAPCAN #<Interpreted Function # {480BDF11}> ARGS)
; --> LET
; ==>
;   #<Interpreted Function (LAMBDA # #) {480BDF11}>
; Error: Cannot dump objects of type EVAL:INTERPRETED-FUNCTION into fasl 
files.
;
; Converted ALLF.
; File: /u/antony/test2.lisp
; In: DEFMACRO ALLF
;   (MAPCAN #<Interpreted Function # {480BDF11}> ARGS)
; --> LET LET DO-ANONYMOUS BLOCK LET
; ==>
;   ARGS
; Note: Deleting unreachable code.
;
; Compiling DEFMACRO ALLF:
; Byte Compiling Top-Level Form:

; Compilation unit finished.
;   2 errors
;   3 notes
; test2.x86f written.
; Compilation finished in 0:00:00.

#p"/u/antony/test2.x86f"
T
T
----------------------------------------------------------------
allf simply fails to work
I noticed that
*  (macroexpand '(with-gensyms ( x y z) (+ x y z)))
;
(LET ((X (GENSYM)) (Y (GENSYM)) (Z (GENSYM)))
   (+ X Y Z))
T

looks to be fine on cmucl.
Whereas allf fails -
* (setf a 1 b 2 c 3)
;
Warning:  Declaring A special.
Warning:  Declaring B special.
Warning:  Declaring C special.

3
* (allf 10 x y z)
;

; Warning: This variable is undefined:
;   GVAL


Error in KERNEL::UNBOUND-SYMBOL-ERROR-HANDLER:  the variable GVAL is 
unbound.
.........

The code also seems to be undumpable as a fasl file in cmucl.
I have a feeling that I may have to learn about eval-when.
Can someone explain what is going on.

Thanks,
-Antony

From: Barry Margolin
Subject: Re: onlisp with-gensyms and allf macro question
Date: 
Message-ID: <barmar-5D397F.01511719052004@comcast.dca.giganews.com>
In article <···················@newssvr29.news.prodigy.com>,
 Antony Sequeira <·············@hotmail.com> wrote:

> Hi
> I am reading OnLisp trying to learn macros.
> I am having trouble with the following two
> 
> ;;pp. 145
> ;;evaluate a body with bunch of symbols in list syms set to gensyms
> (defmacro with-gensyms (syms &body body)
>    `(let ,(mapcar #�(lambda (s)
>                       `(,s (gensym)))
>                     syms)
>      ,@body))
> 
> ;;pp. 169
> ;;sets a bunch of varibales in args to the value val
> (defmacro allf (val &rest args)
>    (with-gensyms (gval)
>      `(let ((,gval ,val))
>        (setf ,@(mapcan #�(lambda (a) (list a gval))
>                          args)))))

Since WITH-GENSYMS is being used in the computation of the macro, not 
its expansion, you need to ensure that the definition is in the 
compile-time environment.  So you have to use EVAL-WHEN:

(eval-when (:compile-toplevel :load-toplevel :execute)
  (defmacro with-gensyms ...))

-- 
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
From: Antony Sequeira
Subject: Re: onlisp with-gensyms and allf macro question
Date: 
Message-ID: <3QNqc.69121$9d1.52461@newssvr25.news.prodigy.com>
Barry Margolin wrote:

> In article <···················@newssvr29.news.prodigy.com>,
>  Antony Sequeira <·············@hotmail.com> wrote:
>>Hi
>>I am reading OnLisp trying to learn macros.
>>I am having trouble with the following two
>>
>>;;pp. 145
>>;;evaluate a body with bunch of symbols in list syms set to gensyms
>>(defmacro with-gensyms (syms &body body)
>>   `(let ,(mapcar #�(lambda (s)
>>                      `(,s (gensym)))
>>                    syms)
>>     ,@body))
>>
>>;;pp. 169
>>;;sets a bunch of varibales in args to the value val
>>(defmacro allf (val &rest args)
>>   (with-gensyms (gval)
>>     `(let ((,gval ,val))
>>       (setf ,@(mapcan #�(lambda (a) (list a gval))
>>                         args)))))
> 
> 
> Since WITH-GENSYMS is being used in the computation of the macro, not 
> its expansion, you need to ensure that the definition is in the 
> compile-time environment.  So you have to use EVAL-WHEN:
> 
> (eval-when (:compile-toplevel :load-toplevel :execute)
>   (defmacro with-gensyms ...))
> 
Thank you, that worked.

Now I am trying to understand what is going on.
Is the eval needed because 'allf' executes 'with-gensyms' during the 
generation of the expansion (I know I am likely rephrasing what you said 
already)?
So it is the allf macro that is the cause of the issue and not the 
with-gensyms macro ?

Assuming I understand correctly, I find this interesting, cause it 
implies if I were to write a macro that needs to use another macro (that 
is say in a third party library), I have to be able to change its eval 
time to use it. How is that done ?

-Antony
From: Pascal Costanza
Subject: Re: onlisp with-gensyms and allf macro question
Date: 
Message-ID: <c8ghv2$4g9$1@newsreader2.netcologne.de>
Antony Sequeira wrote:

> Assuming I understand correctly, I find this interesting, cause it 
> implies if I were to write a macro that needs to use another macro (that 
> is say in a third party library), I have to be able to change its eval 
> time to use it. How is that done ?

If it's in a different library, you can just first load that library, 
and then go on.


Pascal

-- 
1st European Lisp and Scheme Workshop
June 13 - Oslo, Norway - co-located with ECOOP 2004
http://www.cs.uni-bonn.de/~costanza/lisp-ecoop/
From: Antony Sequeira
Subject: Re: onlisp with-gensyms and allf macro question
Date: 
Message-ID: <aRQqc.69165$jn2.8863@newssvr25.news.prodigy.com>
Pascal Costanza wrote:

> 
> 
> Antony Sequeira wrote:
> 
>> Assuming I understand correctly, I find this interesting, cause it 
>> implies if I were to write a macro that needs to use another macro 
>> (that is say in a third party library), I have to be able to change 
>> its eval time to use it. How is that done ?
> 
> 
> If it's in a different library, you can just first load that library, 
> and then go on.
> 
> 
> Pascal
> 
I put the two macros in different files, compiled in appropriate order 
without using eval-when. That worked.
Now I am a bit confused. I only called compile-file on files that 
contained the two macros with-gensyms and allf, one in each file. I did 
not call load.
How come the cmucl REPL allows me to run the macro allf. Does this mean 
compile-file has the side effects of defining the macros and not just 
compiling ? But the functions get defined only after load ?

So, would the rule for builds be
1. If a macro X reuqires macro Y for expansion, you have to *compile* 
the file with macro Y first.
2. If a macro X requires a function Z, you have to *compile and load* 
the file with Z before compiling the file with X. (ignoring it is 
possible to use load without having compiled)
Am I getting this right ?

Thanks for the help.
-Antony
From: Pascal Costanza
Subject: Re: onlisp with-gensyms and allf macro question
Date: 
Message-ID: <c8id9n$qg9$1@newsreader2.netcologne.de>
Antony Sequeira wrote:

> I put the two macros in different files, compiled in appropriate order 
> without using eval-when. That worked.
> Now I am a bit confused. I only called compile-file on files that 
> contained the two macros with-gensyms and allf, one in each file. I did 
> not call load.
> How come the cmucl REPL allows me to run the macro allf. Does this mean 
> compile-file has the side effects of defining the macros and not just 
> compiling ? But the functions get defined only after load ?

I don't know - that's a question for the CMUCL developers.

> So, would the rule for builds be
> 1. If a macro X reuqires macro Y for expansion, you have to *compile* 
> the file with macro Y first.
> 2. If a macro X requires a function Z, you have to *compile and load* 
> the file with Z before compiling the file with X. (ignoring it is 
> possible to use load without having compiled)
> Am I getting this right ?

The COMPILE-FILE entry in the HyperSpec doesn't say anything about 
automatically loading definitions, so this seems to be 
implementation-specific behavior that you probably cannot rely on when 
switching to a different CL implementation.

Your questions suggest that you might want to take a look at one of the 
various system definition facilities, like ASDF and MK:DEFSYSTEM


Pascal

-- 
1st European Lisp and Scheme Workshop
June 13 - Oslo, Norway - co-located with ECOOP 2004
http://www.cs.uni-bonn.de/~costanza/lisp-ecoop/
From: Eric Marsden
Subject: Re: onlisp with-gensyms and allf macro question
Date: 
Message-ID: <wzivfipanac.fsf@melbourne.laas.fr>
>>>>> "as" == Antony Sequeira <·············@hotmail.com> writes:

  as> How come the cmucl REPL allows me to run the macro allf. Does this
  as> mean compile-file has the side effects of defining the macros and not
  as> just compiling ? But the functions get defined only after load ?

  the phenomenom you are seeing can be called leakage from the
  compile-time environment to the evaluation environment; the degree
  of leakage is implementation-dependent. There is an entry on this
  subject in the CMUCL FAQ.

     <http://www.cons.org/cmucl/FAQ.html>
    
-- 
Eric Marsden                          <URL:http://www.laas.fr/~emarsden/>
From: Antony Sequeira
Subject: Re: onlisp with-gensyms and allf macro question
Date: 
Message-ID: <aGqrc.51993$sD.12492@newssvr29.news.prodigy.com>
Eric Marsden wrote:
>>>>>>"as" == Antony Sequeira <·············@hotmail.com> writes:
> 
> 
>   as> How come the cmucl REPL allows me to run the macro allf. Does this
>   as> mean compile-file has the side effects of defining the macros and not
>   as> just compiling ? But the functions get defined only after load ?
> 
>   the phenomenom you are seeing can be called leakage from the
>   compile-time environment to the evaluation environment; the degree
>   of leakage is implementation-dependent. There is an entry on this
>   subject in the CMUCL FAQ.
> 
>      <http://www.cons.org/cmucl/FAQ.html>
>     
It is entry # 16 in the FAQ. Thanks for pointing.
-Antony