From: ThaDoctor
Subject: howto use defmacro.
Date: 
Message-ID: <1181159510.678491.58890@i13g2000prf.googlegroups.com>
HI I would like to know about two things right now.
defmacro is one of the more tricky parts of common lisp, I am learning
common lisp - I come almost fresh to common lisp, that I have only
learned perl before I think that common lisp is really great, with the
macro I think that's really good.

Besides I would also like to know about how to write a new language on
top of lisp, but I would really like to know about a good tutorial on
defmacro.
:=]

greetings from Denmark

From: Jens Teich
Subject: Re: howto use defmacro.
Date: 
Message-ID: <u8xaw3gn2.fsf@jensteich.de>
ThaDoctor <···········@gmail.com> writes:

> HI I would like to know about two things right now.
> defmacro is one of the more tricky parts of common lisp, I am learning
> common lisp - I come almost fresh to common lisp, that I have only
> learned perl before I think that common lisp is really great, with the
> macro I think that's really good.
>
> Besides I would also like to know about how to write a new language on
> top of lisp, but I would really like to know about a good tutorial on
> defmacro.
> :=]
>
> greetings from Denmark

http://gigamonkeys.com/book/

jens
-- 
http://jensteich.de
From: Pascal Bourguignon
Subject: Re: howto use defmacro.
Date: 
Message-ID: <87k5ugsnkv.fsf@thalassa.lan.informatimago.com>
ThaDoctor <···········@gmail.com> writes:

> HI I would like to know about two things right now.
> defmacro is one of the more tricky parts of common lisp, I am learning
> common lisp - I come almost fresh to common lisp, that I have only
> learned perl before I think that common lisp is really great, with the
> macro I think that's really good.

???  defmacro is one of the simpliest parts of CL!

Macros are just compiler plugins.  

Imagine you want to make a new control structure ifnot:

    (ifnot (= a b)
       (print "a is different from b")
       (print "a is equal to b"))

To plug such a control structure in the CL compiler, you write:

(defmacro ifnot (&whole form   test when-false when-true)
   (transform-ifnot form))


So now you only have to implement a simple function named
transform-ifnot, that takes an ifnot form, that is, the source sexp,
like:

    (ifnot (= a b)
       (print "a is different from b")
       (print "a is equal to b"))

and that should some other form.  You can do that no?  Write a simple
function taking a list and returning a list?  It shouldn't be too hard.

Well, that's all there is to macros.



(defun transform-ifnot (form)
  (destructuring-bind (ifnot test when-false when-true) form
     (list 'if (list 'not test) when-false when-true)))



C/USER[43]> (transform-ifnot '(ifnot (= a b)
                               (print "a is different from b")
                               (print "a is equal to b")))
(IF (NOT (= A B)) (PRINT "a is different from b") (PRINT "a is equal to b"))
C/USER[44]> (let ((b 1))
              (dolist (a '(1 2))
                (ifnot (= a b)
                   (print "a is different from b")
                   (print "a is equal to b"))))

"a is equal to b" 
"a is different from b" 
NIL




Now, of course, when you have a function calling another function, you
can always inline the called inside the callee:

(defmacro ifnot (&whole form   test when-false when-true)
  (destructuring-bind (ifnot test when-false when-true) form
     (list 'if (list 'not test) when-false when-true)))

and since defmacro already does the destructuring-bind of the form,
you can remove it:

(defmacro ifnot (test when-false when-true)
   (list 'if (list 'not test) when-false when-true))



> Besides I would also like to know about how to write a new language on
> top of lisp, but I would really like to know about a good tutorial on
> defmacro.
> :=]

http://www.lisperati.com/casting.html


-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

NOTE: The most fundamental particles in this product are held
together by a "gluing" force about which little is currently known
and whose adhesive power can therefore not be permanently
guaranteed.
From: Dan Bensen
Subject: Re: howto use defmacro.
Date: 
Message-ID: <f47gku$1oq$1@wildfire.prairienet.org>
Pascal Bourguignon wrote:
> ThaDoctor <···········@gmail.com> writes:
> 
>> HI I would like to know about two things right now.
>> defmacro is one of the more tricky parts of common lisp, I am learning
>> common lisp - I come almost fresh to common lisp, that I have only
>> learned perl before I think that common lisp is really great, with the
>> macro I think that's really good.
> 
> ???  defmacro is one of the simpliest parts of CL!

> Imagine you want to make a new control structure ifnot:
>     (ifnot (= a b)
>        (print "a is different from b")
>        (print "a is equal to b"))
> 
> To plug such a control structure in the CL compiler, you write:
> (defmacro ifnot (&whole form   test when-false when-true)
>    (transform-ifnot form))

> (defun transform-ifnot (form)
>   (destructuring-bind (ifnot test when-false when-true) form
>      (list 'if (list 'not test) when-false when-true)))

??? Why so complicated?

(defmacro ifnot (test ifnot else) `(if (not ,test) ,ifnot ,else))

-- 
Dan
www.prairienet.org/~dsb/
From: Pascal Bourguignon
Subject: Re: howto use defmacro.
Date: 
Message-ID: <87fy54sil9.fsf@thalassa.lan.informatimago.com>
Dan Bensen <··········@cyberspace.net> writes:

> Pascal Bourguignon wrote:
>> ThaDoctor <···········@gmail.com> writes:
>> 
>>> HI I would like to know about two things right now.
>>> defmacro is one of the more tricky parts of common lisp, I am learning
>>> common lisp - I come almost fresh to common lisp, that I have only
>>> learned perl before I think that common lisp is really great, with the
>>> macro I think that's really good.
>> ???  defmacro is one of the simpliest parts of CL!
>
>> Imagine you want to make a new control structure ifnot:
>>     (ifnot (= a b)
>>        (print "a is different from b")
>>        (print "a is equal to b"))
>> To plug such a control structure in the CL compiler, you write:
>> (defmacro ifnot (&whole form   test when-false when-true)
>>    (transform-ifnot form))
>
>> (defun transform-ifnot (form)
>>   (destructuring-bind (ifnot test when-false when-true) form
>>      (list 'if (list 'not test) when-false when-true)))
>
> ??? Why so complicated?
>
> (defmacro ifnot (test ifnot else) `(if (not ,test) ,ifnot ,else))

Because this is more complicated.

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

NOTE: The most fundamental particles in this product are held
together by a "gluing" force about which little is currently known
and whose adhesive power can therefore not be permanently
guaranteed.
From: fireblade
Subject: Re: howto use defmacro.
Date: 
Message-ID: <1181217260.188095.218190@n4g2000hsb.googlegroups.com>
On Jun 7, 2:40 am, Pascal Bourguignon <····@informatimago.com> wrote:
> Dan Bensen <··········@cyberspace.net> writes:
> > Pascal Bourguignon wrote:
> >> ThaDoctor <···········@gmail.com> writes:
>
> >>> HI I would like to know about two things right now.
> >>> defmacro is one of the more tricky parts of common lisp, I am learning
> >>> common lisp - I come almost fresh to common lisp, that I have only
> >>> learned perl before I think that common lisp is really great, with the
> >>> macro I think that's really good.
> >> ???  defmacro is one of the simpliest parts of CL!
>
> >> Imagine you want to make a new control structure ifnot:
> >>     (ifnot (= a b)
> >>        (print "a is different from b")
> >>        (print "a is equal to b"))
> >> To plug such a control structure in the CL compiler, you write:
> >> (defmacro ifnot (&whole form   test when-false when-true)
> >>    (transform-ifnot form))
>
> >> (defun transform-ifnot (form)
> >>   (destructuring-bind (ifnot test when-false when-true) form
> >>      (list 'if (list 'not test) when-false when-true)))
>
> > ??? Why so complicated?
>
> > (defmacro ifnot (test ifnot else) `(if (not ,test) ,ifnot ,else))
>
> Because this is more complicated.
>
> --
> __Pascal Bourguignon__                    http://www.informatimago.com/
>
> NOTE: The most fundamental particles in this product are held
> together by a "gluing" force about which little is currently known
> and whose adhesive power can therefore not be permanently
> guaranteed.- Hide quoted text -
>
> - Show quoted text -

Sure , why make it simple when you could make it complicated :)


Slobodan Blazeski
From: Larry Clapp
Subject: Re: howto use defmacro.
Date: 
Message-ID: <slrnf6g1h0.cns.larry@theclapp.ddts.net>
On 2007-06-07, fireblade <·················@gmail.com> wrote:
> On Jun 7, 2:40 am, Pascal Bourguignon <····@informatimago.com> wrote:
>> Dan Bensen <··········@cyberspace.net> writes:
>> > Pascal Bourguignon wrote:
>> >> ThaDoctor <···········@gmail.com> writes:
>>
>> >>> HI I would like to know about two things right now.
>> >>> defmacro is one of the more tricky parts of common lisp, I am
>> >>> learning common lisp - I come almost fresh to common lisp, that
>> >>> I have only learned perl before I think that common lisp is
>> >>> really great, with the macro I think that's really good.
>> >> ???  defmacro is one of the simpliest parts of CL!
>>
>> >> Imagine you want to make a new control structure ifnot:
>> >>     (ifnot (= a b)
>> >>        (print "a is different from b")
>> >>        (print "a is equal to b"))
>> >> To plug such a control structure in the CL compiler, you write:
>> >> (defmacro ifnot (&whole form   test when-false when-true)
>> >>    (transform-ifnot form))
>>
>> >> (defun transform-ifnot (form)
>> >>   (destructuring-bind (ifnot test when-false when-true) form
>> >>      (list 'if (list 'not test) when-false when-true)))
>>
>> > ??? Why so complicated?
>>
>> > (defmacro ifnot (test ifnot else) `(if (not ,test) ,ifnot ,else))
>>
>> Because this is more complicated.
>
> Sure , why make it simple when you could make it complicated :)

Well, but his point is, to a newbie, backquote+comma requires more
effort to explain, and more effort to understand, than LIST.

-- L
From: Dan Bensen
Subject: Re: howto use defmacro.
Date: 
Message-ID: <f4991q$jl6$1@wildfire.prairienet.org>
Larry Clapp wrote:
>>>> ??? Why so complicated?
>>>> (defmacro ifnot (test ifnot else) `(if (not ,test) ,ifnot ,else))
>>> Because this is more complicated.
>> Sure , why make it simple when you could make it complicated :)
> 
> Well, but his point is, to a newbie, backquote+comma requires more
> effort to explain, and more effort to understand, than LIST.

You're probably right about what Pascal meant, but I think the
concern is misplaced, and I don't mean just a little bit.
Beginners don't care about the subtle semantic nuances behind
the syntax, interactions with packages, etc., they just want
a simple system that allows them to start doing the basics.
And there's nothing simpler than a visual template of the code.

I'm also not convinced that backquote/comma is really harder to
understand.  Just say that backquoted code in a defmacro is a
template of the code you want to paste into the program, and
comma allows you to paste code from arguments into the template.
It's fully KISS compliant.  Once the newbie has simple code
templates mastered, you can start talking about symbols, gensyms,
programmatically constructed code, and packages.  But if you start
with that stuff right away to demonstrate how awesome macros are,
most beginners won't know where to start.

-- 
Dan
www.prairienet.org/~dsb/
From: Pascal Bourguignon
Subject: Re: howto use defmacro.
Date: 
Message-ID: <877iqfsqe3.fsf@thalassa.lan.informatimago.com>
Dan Bensen <··········@cyberspace.net> writes:

> Larry Clapp wrote:
>>>>> ??? Why so complicated?
>>>>> (defmacro ifnot (test ifnot else) `(if (not ,test) ,ifnot ,else))
>>>> Because this is more complicated.
>>> Sure , why make it simple when you could make it complicated :)
>> Well, but his point is, to a newbie, backquote+comma requires more
>> effort to explain, and more effort to understand, than LIST.
>
> You're probably right about what Pascal meant, but I think the
> concern is misplaced, and I don't mean just a little bit.
> Beginners don't care about the subtle semantic nuances behind
> the syntax, interactions with packages, etc., they just want
> a simple system that allows them to start doing the basics.
> And there's nothing simpler than a visual template of the code.
>
> I'm also not convinced that backquote/comma is really harder to
> understand.  Just say that backquoted code in a defmacro is a
> template of the code you want to paste into the program, and
> comma allows you to paste code from arguments into the template.
> It's fully KISS compliant.  Once the newbie has simple code
> templates mastered, you can start talking about symbols, gensyms,
> programmatically constructed code, and packages.  But if you start
> with that stuff right away to demonstrate how awesome macros are,
> most beginners won't know where to start.

I guess it would depend if you're addressing a packer newbie or a
mapper newbie.

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

NOTE: The most fundamental particles in this product are held
together by a "gluing" force about which little is currently known
and whose adhesive power can therefore not be permanently
guaranteed.
From: Stefan Mandl
Subject: Re: howto use defmacro.
Date: 
Message-ID: <5cra7sF32b71mU1@mid.dfncis.de>
> You're probably right about what Pascal meant, but I think the
> concern is misplaced, and I don't mean just a little bit.
> Beginners don't care about the subtle semantic nuances behind
> the syntax, interactions with packages, etc., they just want
> a simple system that allows them to start doing the basics.
> And there's nothing simpler than a visual template of the code.

I think that the "template"-model really sets beginners on a wrong track which 
will confuse them a for a long time until they realize what's really going on. I 
wish I had been given Pascal's advice when I was learning about macros.

Regards,
Stefan
From: Dan Bensen
Subject: Re: howto use defmacro.
Date: 
Message-ID: <f4a924$trk$1@wildfire.prairienet.org>
>> Beginners don't care about the subtle semantic nuances behind
>> the syntax, interactions with packages, etc., they just want
>> a simple system that allows them to start doing the basics.
>> And there's nothing simpler than a visual template of the code.

Stefan Mandl wrote:
> I think that the "template"-model really sets beginners on a wrong track 
> which will confuse them a for a long time until they realize what's 
> really going on. I wish I had been given Pascal's advice when I was 
> learning about macros.

Yes, it's too bad if you weren't.  But that doesn't mean it should
be the first explanation you ever see, especially as an introductory
example of how macros are "simple".  Anyway, there are lots of things
that confuse beginners, so I think it's good to start them with
simple templates and build up from there.  I don't think it causes
long-term confusion, but that's just my opinion.

-- 
Dan
www.prairienet.org/~dsb/
From: Joseph Fahey
Subject: Re: howto use defmacro.
Date: 
Message-ID: <87fy47opha.fsf@fabula.org>
>>>>> "db" == Dan Bensen <··········@cyberspace.net> writes:

    >>> Beginners don't care about the subtle semantic nuances behind
    >>> the syntax, interactions with packages, etc., they just want a
    >>> simple system that allows them to start doing the basics.  And
    >>> there's nothing simpler than a visual template of the code.

    db> Stefan Mandl wrote:
    >> I think that the "template"-model really sets beginners on a
    >> wrong track which will confuse them a for a long time until
    >> they realize what's really going on. I wish I had been given
    >> Pascal's advice when I was learning about macros.

    db> Yes, it's too bad if you weren't.  But that doesn't mean it
    db> should be the first explanation you ever see, especially as an
    db> introductory example of how macros are "simple".  Anyway,
    db> there are lots of things that confuse beginners, so I think
    db> it's good to start them with simple templates and build up
    db> from there.  I don't think it causes long-term confusion, but
    db> that's just my opinion.

As either a newb, or someone who was recently a newb, I have to agree
with Pascal and Stefan. I didn't really start to understand macros
until I read _On Lisp_ and started writing functions to generate what
I wanted expanded.

The classic template-style examples for macro writing are misleading
because they lead you to believe that a macro is almost like a
function, except for some wierd commas and backquotes.

Pascal's advice would have helped me too, because it gets you
immediatly to the heart of the problem.

-- Joe


PS: to Dan -- sorry about the e-mail, I used the wrong post command!
(see, once a newb...)
From: Dan Bensen
Subject: Re: howto use defmacro.
Date: 
Message-ID: <f696qi$acr$1@wildfire.prairienet.org>
 >>>>>> "db" == Dan Bensen <··········@cyberspace.net> writes:
 >     >>> Beginners don't care about the subtle semantic nuances behind
 >     >>> the syntax, interactions with packages, etc., they just want a
 >     >>> simple system that allows them to start doing the basics.  And
 >     >>> there's nothing simpler than a visual template of the code.

Joseph Fahey wrote:
 > As either a newb, or someone who was recently a newb, I have to agree
 > with Pascal and Stefan. I didn't really start to understand macros
 > until I read _On Lisp_ and started writing functions to generate what
 > I wanted expanded.

Actually, it looks like I'm at fault for not reading Pascal's message
all the way to the end.  Sorry, Pascal.  I like his final answer a lot,
after he boils down all the other stuff:

 > (defmacro ifnot (test when-false when-true)
 >    (list 'if (list 'not test) when-false when-true))

This is an excellent answer, in fact I like it better than the backquote
form.  It clearly emphasizes that the code is just a list that the
macro returns.  This is exactly what makes Lisp macros so easy to
write.

 > The classic template-style examples for macro writing are misleading
 > because they lead you to believe that a macro is almost like a
 > function, except for some wierd commas and backquotes.

Yes, with the backquote syntax, it's not entirely obvious what's going
on.

 > Pascal's advice would have helped me too, because it gets you
 > immediatly to the heart of the problem.

Pascal's final answer is very good.  My only complaint is that I think
it would be better without the &whole argument and destructuring-bind,
but with some text emphasizing that the macro constructs and returns
a chunk of code, and that the code is just a nested list.

 > PS: to Dan -- sorry about the e-mail, I used the wrong post command!
 > (see, once a newb...)

You mean you emailed me at cyberspace.net? :) :)

-- 
Dan
www.prairienet.org/~dsb/
From: fireblade
Subject: Re: howto use defmacro.
Date: 
Message-ID: <1181215421.393349.122300@p47g2000hsd.googlegroups.com>
On Jun 6, 9:51 pm, ThaDoctor <···········@gmail.com> wrote:
> HI I would like to know about two things right now.
> defmacro is one of the more tricky parts of common lisp, I am learning
> common lisp - I come almost fresh to common lisp, that I have only
> learned perl before I think that common lisp is really great, with the
> macro I think that's really good.
>
> Besides I would also like to know about how to write a new language on
> top of lisp, but I would really like to know about a good tutorial on
> defmacro.
> :=]
>
> greetings from Denmark

If you're fairly fluent with lisp(*) than the best tutorial for
Macros  IMHO is Paul Graham's book On Lisp, available for free at
http://www.paulgraham.com/onlisptext.html.


kindly yours
Slobodan Blazeski

(*) When I say lisp in this group I mean Common Lisp for everything
else I use Lisp family of languages
From: Jeronimo Pellegrini
Subject: Re: howto use defmacro.
Date: 
Message-ID: <f48vkc$6o4$1@aioe.org>
On 2007-06-07, fireblade <·················@gmail.com> wrote:
> On Jun 6, 9:51 pm, ThaDoctor <···········@gmail.com> wrote:
>> HI I would like to know about two things right now.
>> defmacro is one of the more tricky parts of common lisp, I am learning
>> common lisp - I come almost fresh to common lisp, that I have only
>> learned perl before I think that common lisp is really great, with the
>> macro I think that's really good.
>>
>> Besides I would also like to know about how to write a new language on
>> top of lisp, but I would really like to know about a good tutorial on
>> defmacro.
>> :=]
>>
>> greetings from Denmark
>
> If you're fairly fluent with lisp(*) than the best tutorial for
> Macros  IMHO is Paul Graham's book On Lisp, available for free at
> http://www.paulgraham.com/onlisptext.html.

I'm currently reading it, and I really like it so far.

One thing I didn't get, though... In chapter 9, when he talks about
variable capture, he mentions a few different ways to avoid the problem,
but it seems that some of the techniques could have just been ommited,
since they're not good enough?
For example, there is a section about "Avoiding Capture with Packages"
(9.7, on page 130), which suggests that you *could* put all your macros
in a separate package. But then he mentions that this would not really
solve the problem.
I feel like I could have just skipped that section. What did I miss?

Maybe it's just a pedagogical thing -- "let me show you what won't
work"... But it wasn't clear to me that this is the case.

(But this was the only part of the book that didn't flow nicely -- it
 really is a great book)

J.