Kenny Tilton wrote:
>
>
> charlieb wrote:
>
>> I've written a macro that creates a number of defuns but at runtime
>> the defuns don't appear to have been evaluated.
>>
>> I've tested it with clisp 2.30 and 2.31.
>>
>> Cheers.
>> Charlie.
>>
>> Here's the code:
>>
>> (defmacro make-commands (&rest commands)
>> (dolist (cmd commands t)
>> (print
>
> Try:
> (defmacro make-commands (&rest commands)
> `(progn
> ,@(mapcar (lambda (cmd)
> `(defun.....<similar>)) commands)))
>
> kenny
OK that works.
Thanks.
For my next question I will ask why wrapping it in a progn should have
such an effect?
Feel free to point me to docs rather than answering directly.
Cheers.
Charlie.
charlieb <··@privacy.net> writes:
> > charlieb wrote:
[SNIP]
> >> Here's the code:
> >>
> >> (defmacro make-commands (&rest commands)
> >> (dolist (cmd commands t)
> >> (print
[ SNIP]
> For my next question I will ask why wrapping it in a progn should have
> such an effect?
> Feel free to point me to docs rather than answering directly.
What does "print" do? What are you trying to do?
//Ingvar
--
My posts are fair game for anybody who wants to distribute the countless
pearls of wisdom sprinkled in them, as long as I'm attributed.
-- Martin Wisse, in a.f.p
Ingvar Mattsson wrote:
> charlieb <··@privacy.net> writes:
>
>
>>>charlieb wrote:
>
> [SNIP]
>
>>>>Here's the code:
>>>>
>>>>(defmacro make-commands (&rest commands)
>>>> (dolist (cmd commands t)
>>>>(print
>
> [ SNIP]
>
>>For my next question I will ask why wrapping it in a progn should have
>>such an effect?
>>Feel free to point me to docs rather than answering directly.
>
>
> What does "print" do? What are you trying to do?
>
> //Ingvar
The print's just gives a little debugging output. It will give the
expansion of the macro so I can check it, not that it did me alot of
good in this case!
Charlie.
charlieb <··@privacy.net> writes:
> Ingvar Mattsson wrote:
>
> > charlieb <··@privacy.net> writes:
> >
> >>>charlieb wrote:
> > [SNIP]
> >
> >>>>Here's the code:
> >>>>
> >>>>(defmacro make-commands (&rest commands)
> >>>> (dolist (cmd commands t)
> >>>>(print
> > [ SNIP]
> >
> >>For my next question I will ask why wrapping it in a progn should have
> >>such an effect?
> >>Feel free to point me to docs rather than answering directly.
> > What does "print" do? What are you trying to do?
> > //Ingvar
> The print's just gives a little debugging output. It will give the
> expansion of the macro so I can check it, not that it did me alot of
> good in this case!
Use MACROEXPAND and MACROEXPAND-1 for that, would be my general suggestion.
//Ingvar
--
(defun m (a b) (cond ((or a b) (cons (car a) (m b (cdr a)))) (t ())))
Ingvar Mattsson wrote:
[snip]
>
>
> Use MACROEXPAND and MACROEXPAND-1 for that, would be my general suggestion.
>
> //Ingvar
The reason I don't is that I can't seem to make them make sense e.g.
[23]> (defmacro test (&rest body)
`(progn ,@(mapcar (lambda (item) (cons (car item) (cdr item)))
body)))
[24]> (macroexpand (test (print 'a) (print 'b)))
A
B
B ;
NIL
Surely this should give:
(progn (print 'a) (print 'b))
as output not the result of evaluating it.
Am I missing something?
Cheers.
Charlie.
charlieb <··@privacy.net> writes:
> Ingvar Mattsson wrote:
>
> [snip]
>> Use MACROEXPAND and MACROEXPAND-1 for that, would be my general
>> suggestion.
>> //Ingvar
>
> The reason I don't is that I can't seem to make them make sense e.g.
>
> [23]> (defmacro test (&rest body)
> `(progn ,@(mapcar (lambda (item) (cons (car item) (cdr item)))
> body)))
>
> [24]> (macroexpand (test (print 'a) (print 'b)))
> A
> B
> B ;
> NIL
>
> Surely this should give:
> (progn (print 'a) (print 'b))
> as output not the result of evaluating it.
>
> Am I missing something?
A quote:
(macroexpand '(test (print 'a) (print 'b)))
Macroexpand is a function.
Joe Marshall wrote:
> charlieb <··@privacy.net> writes:
>
>
>>Ingvar Mattsson wrote:
>>
>>[snip]
>>
>>>Use MACROEXPAND and MACROEXPAND-1 for that, would be my general
>>>suggestion.
>>>//Ingvar
>>
>>The reason I don't is that I can't seem to make them make sense e.g.
>>
>>[23]> (defmacro test (&rest body)
>> `(progn ,@(mapcar (lambda (item) (cons (car item) (cdr item)))
>> body)))
>>
>>[24]> (macroexpand (test (print 'a) (print 'b)))
>>A
>>B
>>B ;
>>NIL
>>
>>Surely this should give:
>>(progn (print 'a) (print 'b))
>>as output not the result of evaluating it.
>>
>>Am I missing something?
>
>
> A quote:
>
> (macroexpand '(test (print 'a) (print 'b)))
>
> Macroexpand is a function.
Doh!
I think I've exhaused my font of dumb questions ... For today!
Thank-you.
Charlie.
Joe Marshall <···@ccs.neu.edu> writes:
> charlieb <··@privacy.net> writes:
>
> > Ingvar Mattsson wrote:
> >
> > [snip]
> >> Use MACROEXPAND and MACROEXPAND-1 for that, would be my general
> >> suggestion.
> >> //Ingvar
> >
> > The reason I don't is that I can't seem to make them make sense e.g.
> >
> > [23]> (defmacro test (&rest body)
> > `(progn ,@(mapcar (lambda (item) (cons (car item) (cdr item)))
> > body)))
> >
> > [24]> (macroexpand (test (print 'a) (print 'b)))
> > A
> > B
> > B ;
> > NIL
> >
> > Surely this should give:
> > (progn (print 'a) (print 'b))
> > as output not the result of evaluating it.
> >
> > Am I missing something?
>
> A quote:
>
> (macroexpand '(test (print 'a) (print 'b)))
>
> Macroexpand is a function.
Also, you may want to use macroexpand-1 since you mostly care about
what *your* macro expands to.
-Peter
--
Peter Seibel ·····@javamonkey.com
Lisp is the red pill. -- John Fraser, comp.lang.lisp
charlieb wrote:
> Kenny Tilton wrote:
>
>>
>>
>> charlieb wrote:
>>
>>> I've written a macro that creates a number of defuns but at runtime
>>> the defuns don't appear to have been evaluated.
>>>
>>> I've tested it with clisp 2.30 and 2.31.
>>>
>>> Cheers.
>>> Charlie.
>>>
>>> Here's the code:
>>>
>>> (defmacro make-commands (&rest commands)
>>> (dolist (cmd commands t)
>>> (print
>>
>>
>> Try:
>> (defmacro make-commands (&rest commands)
>> `(progn
>> ,@(mapcar (lambda (cmd)
>> `(defun.....<similar>)) commands)))
>>
>> kenny
>
>
> OK that works.
> Thanks.
> For my next question I will ask why wrapping it in a progn should have
> such an effect?
Careful, there were a /lot/ of things going on here, and I jumped over a
bunch of it. As others have pointed out, the PRINT was unusual (I
thought maybe it was leftover from your debugging efforts) and in the
end the macro expanded into nothing more than T (because that is what
the dolist returns and that in turn is what the compiler sees), which
would be legal lisp code and thus seem to be working.
What you might have tried is:
(let (expanded)
(dolist (cmd commands (nreverse expanded))
(push `(....) expanded)))
But then the problem is that the compiler wants one form back, not a
list of them. Hence the `(progn ,@...) trick.
> Feel free to point me to docs rather than answering directly.
Well, it's just as well you did /not/ RTFM, because returning multiple
toplevel[*] forms via `(progn...) is hard to index. :) And I am not sure
how many writers think to address that little issue. Meanwhile the only
thing that pushed me over 30 seconds in my response was stopping for a
sip of coffee. SO ask away. Macros especially will drive you nuts until
you are fluent on read-time vs compile-time vs run-time (and I still
don't know what read-time is, but Burdick says it's different and he
would know).
kenny
* I recently saw something in the spec saying that forms in a top-level
progn are treated as top-level. They think of everything! :)
--
http://tilton-technology.com
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
Your Project Here! http://alu.cliki.net/Industry%20Application
Kenny Tilton <·······@nyc.rr.com> writes:
> charlieb wrote:
>
> > Feel free to point me to docs rather than answering directly.
>
> Well, it's just as well you did /not/ RTFM, because returning multiple
> toplevel[*] forms via `(progn...) is hard to index. :) And I am not sure
> how many writers think to address that little issue.
I don't want to counter the "just go ahead and ask here" message
Kenny's trying to convey -- but I'm pretty sure Paul Graham does
address this in _On Lisp_. I remember having an "aha!" moment about
this subject when reading it. (Where *is* my copy of that book?)
> Macros especially will drive you nuts until
> you are fluent on read-time vs compile-time vs run-time (and I still
> don't know what read-time is, but Burdick says it's different and he
> would know).
* (defvar *source*
"(defun foo ()
(let ((message #.(progn (print :read-time-here) :the-message)))
(macrolet ((do-the-damn-thing ()
(print :macro-expand/compile-time-here)
'(print message)))
(do-the-damn-thing))))")
*SOURCE*
* (read-from-string *source*)
:READ-TIME-HERE
(DEFUN FOO ()
(LET ((MESSAGE :THE-MESSAGE))
(MACROLET ((DO-THE-DAMN-THING ()
(PRINT :MACRO-EXPAND/COMPILE-TIME-HERE)
'(PRINT MESSAGE)))
(DO-THE-DAMN-THING))))
263
* (eval *)
FOO
* (compile *)
Compiling LAMBDA NIL:
Compiling Top-Level Form:
:MACRO-EXPAND/COMPILE-TIME-HERE
FOO
NIL
NIL
* (foo)
:THE-MESSAGE
:THE-MESSAGE
--
/|_ .-----------------------.
,' .\ / | No to Imperialist war |
,--' _,' | Wage class war! |
/ / `-----------------------'
( -. |
| ) |
(`-. '--.)
`. )----'
Thomas F. Burdick wrote:
> Kenny Tilton <·······@nyc.rr.com> writes:
>
>
>>charlieb wrote:
>>
>>
>>>Feel free to point me to docs rather than answering directly.
>>
>>Well, it's just as well you did /not/ RTFM, because returning multiple
>>toplevel[*] forms via `(progn...) is hard to index. :) And I am not sure
>>how many writers think to address that little issue.
>
>
> I don't want to counter the "just go ahead and ask here" message
> Kenny's trying to convey -- but I'm pretty sure Paul Graham does
> address this in _On Lisp_. I remember having an "aha!" moment about
> this subject when reading it. (Where *is* my copy of that book?)
PWUAHHHAHAHAHAHAH... I have mine right here, but I just looked in the
index to confirm it is damn hard to look up. I found a couple of
promising leads, but no winners. Good point, tho, for the OP:
http://www.paulgraham.com/onlisp.html
>
>
>>Macros especially will drive you nuts until
>>you are fluent on read-time vs compile-time vs run-time (and I still
>>don't know what read-time is, but Burdick says it's different and he
>>would know).
>
>
> * (defvar *source*
> "(defun foo ()
> (let ((message #.(progn (print :read-time-here) :the-message)))
> (macrolet ((do-the-damn-thing ()
> (print :macro-expand/compile-time-here)
> '(print message)))
> (do-the-damn-thing))))")
> *SOURCE*
> * (read-from-string *source*)
> :READ-TIME-HERE
> (DEFUN FOO ()
> (LET ((MESSAGE :THE-MESSAGE))
> (MACROLET ((DO-THE-DAMN-THING ()
> (PRINT :MACRO-EXPAND/COMPILE-TIME-HERE)
> '(PRINT MESSAGE)))
> (DO-THE-DAMN-THING))))
> 263
> * (eval *)
> FOO
> * (compile *)
> Compiling LAMBDA NIL:
> Compiling Top-Level Form:
> :MACRO-EXPAND/COMPILE-TIME-HERE
> FOO
> NIL
> NIL
> * (foo)
> :THE-MESSAGE
> :THE-MESSAGE
>
--
http://tilton-technology.com
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
Your Project Here! http://alu.cliki.net/Industry%20Application
Kenny Tilton <·······@nyc.rr.com> writes:
> Thomas F. Burdick wrote:
> > Kenny Tilton <·······@nyc.rr.com> writes:
> >
> >
> >>charlieb wrote:
> >>
> >>
> >>>Feel free to point me to docs rather than answering directly.
> >>
> >>Well, it's just as well you did /not/ RTFM, because returning multiple
> >>toplevel[*] forms via `(progn...) is hard to index. :) And I am not sure
> >>how many writers think to address that little issue.
> >
> >
> > I don't want to counter the "just go ahead and ask here" message
> > Kenny's trying to convey -- but I'm pretty sure Paul Graham does
> > address this in _On Lisp_. I remember having an "aha!" moment about
> > this subject when reading it. (Where *is* my copy of that book?)
>
> PWUAHHHAHAHAHAHAH... I have mine right here, but I just looked in the
> index to confirm it is damn hard to look up. I found a couple of
> promising leads, but no winners. Good point, tho, for the OP:
>
> http://www.paulgraham.com/onlisp.html
I think I got it from the first reading of the "Macros" chapter.
Looking back at it, it has the (progn ... ,@(...) ...) idiom in there
a couple times. But you're right, there's no index entry for "Macros,
expansion of, into multiple forms".
--
/|_ .-----------------------.
,' .\ / | No to Imperialist war |
,--' _,' | Wage class war! |
/ / `-----------------------'
( -. |
| ) |
(`-. '--.)
`. )----'
Kenny Tilton wrote:
>
>
> charlieb wrote:
>
>> Kenny Tilton wrote:
[snip]
> Careful, there were a /lot/ of things going on here, and I jumped over a
> bunch of it. As others have pointed out, the PRINT was unusual (I
> thought maybe it was leftover from your debugging efforts) and in the
> end the macro expanded into nothing more than T (because that is what
> the dolist returns and that in turn is what the compiler sees), which
> would be legal lisp code and thus seem to be working.
>
> What you might have tried is:
>
> (let (expanded)
> (dolist (cmd commands (nreverse expanded))
> (push `(....) expanded)))
>
> But then the problem is that the compiler wants one form back, not a
> list of them. Hence the `(progn ,@...) trick.
> [snip]
One hard problem and one easy problem. I've already kicked my own butt
for the easy one but the hard one intregues me. Why should it be the
case that the compiler won't handle multiple forms from a macro? My
naive reasoning goes like this:
Pass one expands the macros, pass two compiles/evaluates the result so
whether a macro results in many forms or just one wouldn't make any
difference as long as they were valid lisp code. but then what do I know!
Charlie.
charlieb <··@privacy.net> writes:
> Kenny Tilton wrote:
>
> > charlieb wrote:
> >
> >> Kenny Tilton wrote:
> [snip]
> > Careful, there were a /lot/ of things going on here, and I jumped
> > over a bunch of it. As others have pointed out, the PRINT was
> > unusual (I thought maybe it was leftover from your debugging
> > efforts) and in the end the macro expanded into nothing more than T
> > (because that is what the dolist returns and that in turn is what
> > the compiler sees), which would be legal lisp code and thus seem to
> > be working.
> > What you might have tried is:
> > (let (expanded)
> > (dolist (cmd commands (nreverse expanded))
> > (push `(....) expanded)))
> > But then the problem is that the compiler wants one form back, not a
> > list of them. Hence the `(progn ,@...) trick.
> > [snip]
>
> One hard problem and one easy problem. I've already kicked my own butt
> for the easy one but the hard one intregues me. Why should it be the
> case that the compiler won't handle multiple forms from a macro? My
> naive reasoning goes like this:
> Pass one expands the macros, pass two compiles/evaluates the result so
> whether a macro results in many forms or just one wouldn't make any
> difference as long as they were valid lisp code. but then what do I
> know!
But what you'd return isn't:
(defun form-1 ...)
(defun form-2 ...)
(defun form-3 ...)
But:
((defun form-1 ...)
(defun form-2 ...)
(defun form-3 ...))
So what you'd want to return is:
(progn
(defun form-1 ...)
(defun form-2 ...)
(defun form-3 ...))
//Ingvar
--
Self-referencing
Five, seven, five syllables
This haiku contains
Ingvar Mattsson wrote:
> charlieb <··@privacy.net> writes:
>
>
>>Kenny Tilton wrote:
>>
>>
>>>charlieb wrote:
>>>
>>>
>>>>Kenny Tilton wrote:
>>
>>[snip]
>>
>>>Careful, there were a /lot/ of things going on here, and I jumped
>>>over a bunch of it. As others have pointed out, the PRINT was
>>>unusual (I thought maybe it was leftover from your debugging
>>>efforts) and in the end the macro expanded into nothing more than T
>>>(because that is what the dolist returns and that in turn is what
>>>the compiler sees), which would be legal lisp code and thus seem to
>>>be working.
>>>What you might have tried is:
>>> (let (expanded)
>>> (dolist (cmd commands (nreverse expanded))
>>> (push `(....) expanded)))
>>>But then the problem is that the compiler wants one form back, not a
>>>list of them. Hence the `(progn ,@...) trick.
>>>[snip]
>>
>>One hard problem and one easy problem. I've already kicked my own butt
>>for the easy one but the hard one intregues me. Why should it be the
>>case that the compiler won't handle multiple forms from a macro? My
>>naive reasoning goes like this:
>>Pass one expands the macros, pass two compiles/evaluates the result so
>>whether a macro results in many forms or just one wouldn't make any
>>difference as long as they were valid lisp code. but then what do I
>>know!
>
>
>
> But what you'd return isn't:
> (defun form-1 ...)
> (defun form-2 ...)
> (defun form-3 ...)
>
> But:
> ((defun form-1 ...)
> (defun form-2 ...)
> (defun form-3 ...))
Ah, yes, that was it. Sorry, CharlieB, I got that wrong. The macro
expands fine and the output being a list is not a problem (hell, a form
/is/ a list), but the output shown above is not acceptable to the
compiler for obvious reasons (the first guy has to be a function or
macro or special form).
In fact, in my macro headbangingagainstthewall days I recall seeing the
above when I macroexpanded some code, before getting to `(progn ,@...).
kenny
>
> So what you'd want to return is:
> (progn
> (defun form-1 ...)
> (defun form-2 ...)
> (defun form-3 ...))
>
> //Ingvar
--
http://tilton-technology.com
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
Your Project Here! http://alu.cliki.net/Industry%20Application
Kenny Tilton <·······@nyc.rr.com> writes:
[ SNIP ]
> stopping for a sip of coffee. SO ask away. Macros especially will
> drive you nuts until you are fluent on read-time vs compile-time vs
> run-time (and I still don't know what read-time is, but Burdick says
> it's different and he would know).
Think things like "read-table modifications" and the joys of #.
//Ingvar
--
(defun m (a b) (cond ((or a b) (cons (car a) (m b (cdr a)))) (t ())))
charlieb <··@privacy.net> writes:
> For my next question I will ask why wrapping it in a progn should have
> such an effect?
Your original macro (slightly reformatted):
(defmacro make-commands (&rest commands)
(dolist (cmd commands t)
(print
`(defun ,(car cmd) (,@(cadr cmd) sock)
(send-command ,(caddr cmd) ,(cadddr cmd) sock
,(if (fifth cmd)
(fifth cmd)
0))))))
expands to nothing more than `t'.
--
Lars Brinkhoff, Services for Unix, Linux, GCC, HTTP
Brinkhoff Consulting http://www.brinkhoff.se/
Lars Brinkhoff wrote:
> charlieb <··@privacy.net> writes:
>
>>For my next question I will ask why wrapping it in a progn should have
>>such an effect?
>
>
> Your original macro (slightly reformatted):
>
> (defmacro make-commands (&rest commands)
> (dolist (cmd commands t)
> (print
> `(defun ,(car cmd) (,@(cadr cmd) sock)
> (send-command ,(caddr cmd) ,(cadddr cmd) sock
> ,(if (fifth cmd)
> (fifth cmd)
> 0))))))
>
> expands to nothing more than `t'.
>
Oh yeah, <kicks own butt>. Next time I'll put the print at the top of
the macro!
Cheers.
Charlie.
In article <···············@ID-208832.news.uni-berlin.de>,
charlieb <··@privacy.net> wrote:
>Oh yeah, <kicks own butt>. Next time I'll put the print at the top of
>the macro!
Or you could just use MACROEXPAND to see what your macro expands into.
That way your instrumentation shouldn't affect the behavior of the macro
itself.
--
Barry Margolin, ··············@level3.com
Level(3), Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
Kenny Tilton <·······@nyc.rr.com> writes:
> Try:
> (defmacro make-commands (&rest commands)
> `(progn
> ,@(mapcar (lambda (cmd)
> `(defun.....<similar>)) commands)))
Or:
(defmacro make-commands (&rest commands)
`(eval-when (:compile-toplevel, :load-toplevel, :execute)
,@(mapcar (lambda (cmd)
`(defun.....<similar>)) commands)))
if you want to be able to use the function defined in following macros.
A `(progn ...) macro would generate code that would be executed only
at load-time or run-time, but macro, since they're executed at
compilation-time, can access only functions that are defined at
compilation-time (but they can still generate code calling functions
that won't be defined until execution time).
In your macro, progn and defun are called at load/run time, while
mapcar is called at compilation time.
--
__Pascal_Bourguignon__
http://www.informatimago.com/
Pascal Bourguignon <····@thalassa.informatimago.com> writes:
> Kenny Tilton <·······@nyc.rr.com> writes:
> > Try:
> > (defmacro make-commands (&rest commands)
> > `(progn
> > ,@(mapcar (lambda (cmd)
> > `(defun.....<similar>)) commands)))
>
> Or:
>
> (defmacro make-commands (&rest commands)
> `(eval-when (:compile-toplevel, :load-toplevel, :execute)
> ,@(mapcar (lambda (cmd)
> `(defun.....<similar>)) commands)))
>
> if you want to be able to use the function defined in following macros.
>
> A `(progn ...) macro would generate code that would be executed only
> at load-time or run-time, but macro, since they're executed at
> compilation-time, can access only functions that are defined at
> compilation-time (but they can still generate code calling functions
> that won't be defined until execution time).
>
> In your macro, progn and defun are called at load/run time, while
> mapcar is called at compilation time.
No, PROGN maintains the toplevel-ness of the forms it contains. So in
(progn (defun a ()) (defun b ()) (defun c())) all three defuns are at
toplevel.
--
/|_ .-----------------------.
,' .\ / | No to Imperialist war |
,--' _,' | Wage class war! |
/ / `-----------------------'
( -. |
| ) |
(`-. '--.)
`. )----'
···@famine.OCF.Berkeley.EDU (Thomas F. Burdick) writes:
>
> No, PROGN maintains the toplevel-ness of the forms it contains. So in
> (progn (defun a ()) (defun b ()) (defun c())) all three defuns are at
> toplevel.
Thank you to correct me, you're right indeed.
--
__Pascal_Bourguignon__
http://www.informatimago.com/