From: Majorinc, Kazimir
Subject: What is the main advantage of macros over functions?
Date: 
Message-ID: <MPG.1e263133d8d093879898ad@news.carnet.hr>
I've frequently read that macros are one of the most important 
strengths of Lisp, however, I do not understand why. 

Only advantage of Lisp macros over Lisp functions I see are 
slight increase of the speed and few quotes and perhaps 
arguments less. Not really much ...

Am I missing something here? 

From: justinhj
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <1136401171.154784.131770@z14g2000cwz.googlegroups.com>
Majorinc wrote:
> I've frequently read that macros are one of the most important
> strengths of Lisp, however, I do not understand why.
>
> Only advantage of Lisp macros over Lisp functions I see are
> slight increase of the speed and few quotes and perhaps
> arguments less. Not really much ...
>
> Am I missing something here?

Yes have a read of the introduction and relevant parts of Paul Graham's
book On Lisp

http://www.paulgraham.com/onlisp.html

There is a philisophy of lisp programming which is that you use lisp to
write the language you want to solve your problem, then write the
solution to your problem in that new language. Macros provide a core
part of that process since you can drastically change the language
using them.

Justin
From: Joe Marshall
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <1136404695.588875.161510@g14g2000cwa.googlegroups.com>
What is the advantage of conditionals over data structures?
What is the advantage of Unicode over lightweight threads?

Macros are a means to modify the *syntax* of the language.  Functions
are a means to modify the *behavior* of the language.  Using one as a
substitute for the other is as nonsensical as the questions above.
From: Jeff M.
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <1136407900.424928.4030@g47g2000cwa.googlegroups.com>
What do lex and yacc (http://dinosaur.compilertools.net/) do? They
generate C code (as a precompile step) that then gets compiled into
your project. Why are they important? After all, you could write a
parser by hand to do the same thing?

Answer those, and you've answered your own question...

Lisp macros execute at compile time, and leverages the entire language
to do so. Functions execute at runtime.

Jeff M.
From: Geoffrey Summerhayes
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <3ZUuf.1890$H37.312041@news20.bellglobal.com>
<Majorinc>; "Kazimir" <·····@email.address> wrote in message 
·······························@news.carnet.hr...
> I've frequently read that macros are one of the most important
> strengths of Lisp, however, I do not understand why.
>
> Only advantage of Lisp macros over Lisp functions I see are
> slight increase of the speed and few quotes and perhaps
> arguments less. Not really much ...
>
> Am I missing something here?

Tonnes. Try writing a version of WHEN or UNLESS as a function,
it will not work correctly. You can't write a special form, but
you can fake one with a macro. And that's just one thing.

Read 'On Lisp' by Graham, it's a real eye opener.

http://www.paulgraham.com/onlisp.html

--
Geoff
From: Pascal Costanza
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <4230blF1hdsfbU1@individual.net>
Geoffrey Summerhayes wrote:
> <Majorinc>; "Kazimir" <·····@email.address> wrote in message 
> ·······························@news.carnet.hr...
> 
>>I've frequently read that macros are one of the most important
>>strengths of Lisp, however, I do not understand why.
>>
>>Only advantage of Lisp macros over Lisp functions I see are
>>slight increase of the speed and few quotes and perhaps
>>arguments less. Not really much ...
>>
>>Am I missing something here?
> 
> Tonnes. Try writing a version of WHEN or UNLESS as a function,
> it will not work correctly. You can't write a special form, but
> you can fake one with a macro. And that's just one thing.

(defun when (condition block)
   (if condition
      (funcall block)))

(when (< 0 1)
   (lambda ()
     (print 'foo)))

I know this is silly, but some people have a really hard time to 
understand the advantage over the following code.

(defmacro when (condition &body body)
   `(if ,condition
       (progn ,@body)))

(when (< 0 1)
   (print 'foo))

The important difference, IMHO, is that the former leaks implementation 
details while the latter doesn't.


Pascal

-- 
My website: http://p-cos.net
Closer to MOP & ContextL:
http://common-lisp.net/project/closer/
From: Adrian Kubala
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <slrndrq7h3.cga.adrian-news@sixfingeredman.net>
On 2006-01-04, Pascal Costanza <··@p-cos.net> wrote:
> (defun when (condition block)
>    (if condition
>       (funcall block)))
>
> (when (< 0 1)
>    (lambda ()
>      (print 'foo)))
>
> I know this is silly, but some people have a really hard time to 
> understand the advantage over the following code.
>
> (defmacro when (condition &body body)
>    `(if ,condition
>        (progn ,@body)))
>
> (when (< 0 1)
>    (print 'foo))
>
> The important difference, IMHO, is that the former leaks implementation 
> details while the latter doesn't.

I'm not anti-macro, but in this case, how is the fact that the body of
the when should be delayed an implementation detail? It's the whole
point of when.
From: André Thieme
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <1136473976.434772.159670@o13g2000cwo.googlegroups.com>
Take a look at:
http://www.gigamonkeys.com/book/macros-defining-your-own.html

If you don't want to read everything scroll down to "Plugging the
Leaks" and you will find a good explanation.


André
--
From: Pascal Bourguignon
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <87u0ciep58.fsf@thalassa.informatimago.com>
Adrian Kubala <···········@sixfingeredman.net> writes:

> On 2006-01-04, Pascal Costanza <··@p-cos.net> wrote:
>> (defun when (condition block)
>>    (if condition
>>       (funcall block)))
>>
>> (when (< 0 1)
>>    (lambda ()
>>      (print 'foo)))
>>
>> I know this is silly, but some people have a really hard time to 
>> understand the advantage over the following code.
>>
>> (defmacro when (condition &body body)
>>    `(if ,condition
>>        (progn ,@body)))
>>
>> (when (< 0 1)
>>    (print 'foo))
>>
>> The important difference, IMHO, is that the former leaks implementation 
>> details while the latter doesn't.
>
> I'm not anti-macro, but in this case, how is the fact that the body of
> the when should be delayed an implementation detail? It's the whole
> point of when.

Well, if you only consider lambda calculus, it cannot be called an
implementation detail, because everything is lambda.  Then the point
of macros is to remove all these lambdas that are low-level stuff we
don't mind (syntactic abstraction).

But when could also be implemented with another primitive:

(defmacro when (condition &body body)
  (let ((end (gensym)))
    `(tagbody
       (if (not ,condition) (go ,end))
       (progn ,@body)
       ,end)))

so the choice between a lambda calculus or a von-newman computer is
indeed an implementation detail, and a WHEN macro can hide this
unrelevant implementation choice in your algorithms, while a WHEN
function couldn't.


Or, said otherwise, if you're wondering why macros are useful, try to
write a lisp program without _using_ any predefined lisp macro.


Writing:

   ((lambda (a) 
        ((lambda (b) (print a) (print (1+ b)))  (* 2 a))) 42)

for:

   (let* ((a 42)
          (b (* 2 a)))
       (print a)
       (print b))

will grow old really fast.


-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
Our enemies are innovative and resourceful, and so are we. They never
stop thinking about new ways to harm our country and our people, and
neither do we. -- Georges W. Bush
From: Adrian Kubala
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <slrndrqgad.d5j.adrian-news@sixfingeredman.net>
On 2006-01-05, Pascal Bourguignon <····@mouse-potato.com> wrote:
>> I'm not anti-macro, but in this case, how is the fact that the body of
>> the when should be delayed an implementation detail? It's the whole
>> point of when.
>
> Well, if you only consider lambda calculus, it cannot be called an
> implementation detail, because everything is lambda.  Then the point
> of macros is to remove all these lambdas that are low-level stuff we
> don't mind (syntactic abstraction).
>
> But when could also be implemented with another primitive:
> [...]
> so the choice between a lambda calculus or a von-newman computer is
> indeed an implementation detail, and a WHEN macro can hide this
> unrelevant implementation choice in your algorithms, while a WHEN
> function couldn't.

That's like saying that the choice between Church numerals and integers
as arguments to + is an implementation detail. Sure, there are all kinds
of ways you could obfuscate the lambda, but (and maybe this is just my
personal aesthetics talking) seen as an abstract concept, it's right
there anyways, inherent in the definition of "when". 

Mostly I think that using macros to paper over lambdas is an
unconvincing argument for why macros are good even if that's mostly what
Lisp uses them for. People should hear about CPS transformers, parser
generators, etc instead.
From: Pascal Costanza
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <424vvgF1h7oguU1@individual.net>
Adrian Kubala wrote:
> On 2006-01-05, Pascal Bourguignon <····@mouse-potato.com> wrote:
> 
>>>I'm not anti-macro, but in this case, how is the fact that the body of
>>>the when should be delayed an implementation detail? It's the whole
>>>point of when.
>>
>>Well, if you only consider lambda calculus, it cannot be called an
>>implementation detail, because everything is lambda.  Then the point
>>of macros is to remove all these lambdas that are low-level stuff we
>>don't mind (syntactic abstraction).
>>
>>But when could also be implemented with another primitive:
>>[...]
>>so the choice between a lambda calculus or a von-newman computer is
>>indeed an implementation detail, and a WHEN macro can hide this
>>unrelevant implementation choice in your algorithms, while a WHEN
>>function couldn't.
> 
> That's like saying that the choice between Church numerals and integers
> as arguments to + is an implementation detail.

Well, it is. Or do you think it should be obvious from the source code 
what encoding of numbers is used internally?

> Sure, there are all kinds
> of ways you could obfuscate the lambda, but (and maybe this is just my
> personal aesthetics talking) seen as an abstract concept, it's right
> there anyways, inherent in the definition of "when".

At least one version didn't have a lambda, not even inherently.

> Mostly I think that using macros to paper over lambdas is an
> unconvincing argument for why macros are good even if that's mostly what
> Lisp uses them for. People should hear about CPS transformers, parser
> generators, etc instead.

Note that I have already said it's a silly example. However, I think 
it's a nice toy example because it shows the difference between 
functional abstractions and syntactic abstractions in a very concise way.


Pascal

-- 
My website: http://p-cos.net
Closer to MOP & ContextL:
http://common-lisp.net/project/closer/
From: Pascal Costanza
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <424oe6F1h87pkU1@individual.net>
Adrian Kubala wrote:
> On 2006-01-04, Pascal Costanza <··@p-cos.net> wrote:
> 
>>(defun when (condition block)
>>   (if condition
>>      (funcall block)))
>>
>>(when (< 0 1)
>>   (lambda ()
>>     (print 'foo)))
>>
>>I know this is silly, but some people have a really hard time to 
>>understand the advantage over the following code.
>>
>>(defmacro when (condition &body body)
>>   `(if ,condition
>>       (progn ,@body)))
>>
>>(when (< 0 1)
>>   (print 'foo))
>>
>>The important difference, IMHO, is that the former leaks implementation 
>>details while the latter doesn't.
> 
> I'm not anti-macro, but in this case, how is the fact that the body of
> the when should be delayed an implementation detail? It's the whole
> point of when.

Here are two other implementations of 'when:

(defun when-fun (condition block)
   (if condition (funcall block)))

(defmacro when-1 (condition &body body)
   `(when-fun ,condition (lambda () ,@body)))

(defmacro when-2 (condition &body body)
   (let ((end (gensym))
         (result (gensym)))
     `(prog (,result)
        (if (not ,condition) (go ,end))
        (setq ,result (progn ,@body))
        ,end ,result)))

The differences between when, when-1 and when-2 are implementation 
details because they don't matter to the user. The only thing that 
matters to the user is that a condition is checked and that some code is 
executed based on the result of that check.

'when-fun leaks an implementation detail because you have to explicitly 
pass a lambda expression. However, it shouldn't matter to you how the 
delay of the when body is achieved.

This is the kind of abstraction that cannot be achieved with functions. 
Hence macros are also called syntactic abstractions.

Pascal

-- 
My website: http://p-cos.net
Closer to MOP & ContextL:
http://common-lisp.net/project/closer/
From: Pascal Bourguignon
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <87hd8ienj2.fsf@thalassa.informatimago.com>
Pascal Costanza <··@p-cos.net> writes:

> (defmacro when-2 (condition &body body)
>    (let ((end (gensym))
>          (result (gensym)))
>      `(prog (,result)
>         (if (not ,condition) (go ,end))
>         (setq ,result (progn ,@body))
>         ,end ,result)))

Yes, I forgot that TAGBODY returns NIL.


> This is the kind of abstraction that cannot be achieved with
> functions. Hence macros are also called syntactic abstractions.

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

HANDLE WITH EXTREME CARE: This product contains minute electrically
charged particles moving at velocities in excess of five hundred
million miles per hour.
From: Geoffrey Summerhayes
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <ZVdvf.2605$H37.405876@news20.bellglobal.com>
"Pascal Costanza" <··@p-cos.net> wrote in message 
····················@individual.net...
>
> (defun when (condition block)
>   (if condition
>      (funcall block)))
>
> (when (< 0 1)
>   (lambda ()
>     (print 'foo)))
>
> I know this is silly, but some people have a really hard time to 
> understand the advantage over the following code.
>
> (defmacro when (condition &body body)
>   `(if ,condition
>       (progn ,@body)))
>
> (when (< 0 1)
>   (print 'foo))
>
> The important difference, IMHO, is that the former leaks implementation 
> details while the latter doesn't.

I use top-down development quite a bit, so more important to my mind
is that it violates WHENs design contract (when test form*), which
means I have to rewrite everything that uses it. :(

--
Geoff
From: Majorinc, Kazimir
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <MPG.1e278be48c3e487989686@news.carnet.hr>
In article <·····················@news20.bellglobal.com>, 
·············@hotmail.com says...
> 
> <Majorinc>; "Kazimir" <·····@email.address> wrote in message 
> ·······························@news.carnet.hr...
> > I've frequently read that macros are one of the most important
> > strengths of Lisp, however, I do not understand why.
> >
> > Only advantage of Lisp macros over Lisp functions I see are
> > slight increase of the speed and few quotes and perhaps
> > arguments less. Not really much ...
> >
> > Am I missing something here?
> 
> Tonnes. Try writing a version of WHEN or UNLESS as a function,
> it will not work correctly. You can't write a special form, but
> you can fake one with a macro. And that's just one thing.

I think that simplest possible definition works:

(defun my-when (x y) (if x y nil) )

Of course

(my-when a b)

does not work, but

(eval (my-when a 'b))

does, and it is almost the same thing. Bit longer, but it has 
some advantages over macro solution as well. 
From: Pascal Costanza
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <4259gpF1hcg7qU1@individual.net>
Majorinc wrote:
> In article <·····················@news20.bellglobal.com>, 
> ·············@hotmail.com says...
> 
>><Majorinc>; "Kazimir" <·····@email.address> wrote in message 
>>·······························@news.carnet.hr...
>>
>>>I've frequently read that macros are one of the most important
>>>strengths of Lisp, however, I do not understand why.
>>>
>>>Only advantage of Lisp macros over Lisp functions I see are
>>>slight increase of the speed and few quotes and perhaps
>>>arguments less. Not really much ...
>>>
>>>Am I missing something here?
>>
>>Tonnes. Try writing a version of WHEN or UNLESS as a function,
>>it will not work correctly. You can't write a special form, but
>>you can fake one with a macro. And that's just one thing.
> 
> I think that simplest possible definition works:
> 
> (defun my-when (x y) (if x y nil) )
> 
> Of course
> 
> (my-when a b)
> 
> does not work, but
> 
> (eval (my-when a 'b))
> 
> does, and it is almost the same thing. Bit longer, but it has 
> some advantages over macro solution as well. 

Either you have forgotten a few smileys here, or you haven't understood 
some important concepts yet. Using eval like this is definitely not a 
good idea. It's rarely a good idea to use eval under most circumstances...


Pascal

-- 
My website: http://p-cos.net
Closer to MOP & ContextL:
http://common-lisp.net/project/closer/
From: Majorinc, Kazimir
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <MPG.1e2795c8b630cab3989687@news.carnet.hr>
In article <···············@individual.net>, ··@p-cos.net 
says...

> Either you have forgotten a few smileys here, or you haven't understood 
> some important concepts yet. Using eval like this is definitely not a 
> good idea. It's rarely a good idea to use eval under most circumstances...
> 

Why?
From: Majorinc, Kazimir
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <MPG.1e27981448c53dbc989688@news.carnet.hr>
In article <··························@news.carnet.hr>, 
·······@chem.pmf.hr says...
> In article <···············@individual.net>, ··@p-cos.net 
> says...
> 
> > Either you have forgotten a few smileys here, or you haven't understood 
> > some important concepts yet. Using eval like this is definitely not a 
> > good idea. It's rarely a good idea to use eval under most circumstances...
> > 
> 
> Why?
> 
OH, OK, I've seen your longer post. 
From: Pascal Costanza
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <425c2gF1hjodmU2@individual.net>
Majorinc wrote:
> In article <···············@individual.net>, ··@p-cos.net 
> says...
> 
>>Either you have forgotten a few smileys here, or you haven't understood 
>>some important concepts yet. Using eval like this is definitely not a 
>>good idea. It's rarely a good idea to use eval under most circumstances...
> 
> Why?

See my other reply.

Pascal

-- 
My website: http://p-cos.net
Closer to MOP & ContextL:
http://common-lisp.net/project/closer/
From: John Thingstad
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <op.s2ydldbvpqzri1@mjolner.upc.no>
On Thu, 05 Jan 2006 20:45:42 +0100, <Majorinc> wrote:

> In article <···············@individual.net>, ··@p-cos.net
> says...
>
>> Either you have forgotten a few smileys here, or you haven't understood
>> some important concepts yet. Using eval like this is definitely not a
>> good idea. It's rarely a good idea to use eval under most  
>> circumstances...
>>
>
> Why?

Sigh! You are creating a whole new environment recursivly.
This is extremely expensive.
Also since it's in a new environment you can't see any of you lexical
vaiables. So I think it is fair to say it's not exactly the same.

-- 
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
From: Coby Beck
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <kKVuf.30167$AP5.7242@edtnps84>
<Majorinc>; "Kazimir" <·····@email.address> wrote in message 
·······························@news.carnet.hr...
> I've frequently read that macros are one of the most important
> strengths of Lisp, however, I do not understand why.
>
> Only advantage of Lisp macros over Lisp functions I see are
> slight increase of the speed and few quotes and perhaps
> arguments less. Not really much ...
>
> Am I missing something here?

Only about a hundred previous threads on this topic, that's all.  Are you 
sure you are not just trolling?

Macros are about transforming source code from a high level expression of an 
idea into all the low level nitty-gritty of implementation.  It is 
fundamentally different from a function that operates on data passed to it 
at runtime.  They can of course each accomplish anything the other can with 
sufficient contortions.

-- 
Coby Beck
(remove #\Space "coby 101 @ bigpond . com")
From: Pascal Bourguignon
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <87mzibfz99.fsf@thalassa.informatimago.com>
"Coby Beck" <·····@mercury.bc.ca> writes:

> <Majorinc>; "Kazimir" <·····@email.address> wrote in message 
> ·······························@news.carnet.hr...
>> I've frequently read that macros are one of the most important
>> strengths of Lisp, however, I do not understand why.
>>
>> Only advantage of Lisp macros over Lisp functions I see are
>> slight increase of the speed and few quotes and perhaps
>> arguments less. Not really much ...
>>
>> Am I missing something here?
>
> Only about a hundred previous threads on this topic, that's all.  Are you 
> sure you are not just trolling?

There was recently enough a thread about domain specific languages
where somebody started with a high level expression of an algorithm
and just coded around this form macros and functions to make it
executable.  Unfortunately, I don't find the keywords needed to
retrieve it from google groups :-(  

(We should index interesting threads in the FAQ, Gardeners?  ;-)

Anyways, that's one of the most interesting use of macros. Just write
your data or "knowledge", be it procedural or declarative as it is
most clearly expressed in domain specific terms.  The only constraint
is to put it in s-exp forms, which is good after all because it allow
you to forget about irrelevant details like syntax (domain specific
useless "jargon"), and to keep only the important domain specific
features.

Then you can start to write lisp code to make your domain specific
forms run.


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

NEW GRAND UNIFIED THEORY DISCLAIMER: The manufacturer may
technically be entitled to claim that this product is
ten-dimensional. However, the consumer is reminded that this
confers no legal rights above and beyond those applicable to
three-dimensional objects, since the seven new dimensions are
"rolled up" into such a small "area" that they cannot be
detected.
From: Lars Brinkhoff
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <85u0cj0y9w.fsf@junk.nocrew.org>
Pascal Bourguignon <····@mouse-potato.com> writes:
> There was recently enough a thread about domain specific languages
> where somebody started with a high level expression of an algorithm
> and just coded around this form macros and functions to make it
> executable.  Unfortunately, I don't find the keywords needed to
> retrieve it from google groups :-(

Alan Crowe's "runnable pseudo-code"?

http://groups.google.co.uk/group/comp.lang.lisp/msg/a827235ce7466a92

(See Alan, somone is paying attention to your articles.)
From: Eli Gottlieb
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <_LVuf.83812$ME5.62257@twister.nyroc.rr.com>
Majorinc wrote:
> I've frequently read that macros are one of the most important 
> strengths of Lisp, however, I do not understand why. 
> 
> Only advantage of Lisp macros over Lisp functions I see are 
> slight increase of the speed and few quotes and perhaps 
> arguments less. Not really much ...
> 
> Am I missing something here? 
> 
Macros return code.  Using them you can add new control constructs to 
the language, or encapsulate entire algorithms, in addition to being 
able to pass unevaluated arguments (ie: I can pass "(eval x)" to a macro 
without it being evaluated).

If you notice yourself writing a certain pattern of code over and over, 
chances are it should be a macro.
From: Rainer Joswig
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <BFE29EDD.248F9%joswig@lisp.de>
Am 04.01.2006 20:56 Uhr schrieb "Eli Gottlieb" unter <···········@gmail.com>
in ·····················@twister.nyroc.rr.com:

> Majorinc wrote:
>> I've frequently read that macros are one of the most important
>> strengths of Lisp, however, I do not understand why.
>> 
>> Only advantage of Lisp macros over Lisp functions I see are
>> slight increase of the speed and few quotes and perhaps
>> arguments less. Not really much ...
>> 
>> Am I missing something here?
>> 
> Macros return code.  Using them you can add new control constructs to
> the language, or encapsulate entire algorithms, in addition to being
> able to pass unevaluated arguments (ie: I can pass "(eval x)" to a macro
> without it being evaluated).
> 
> If you notice yourself writing a certain pattern of code over and over,
> chances are it should be a macro.

If you notice yourself writing a certain pattern of code over and over,
chances are it should be a function.
From: Philippe Lorin
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <43bcff8d$0$297$636a55ce@news.free.fr>
Rainer Joswig wrote:
> If you notice yourself writing a certain pattern of code over and over,
> chances are it should be a function.

If you notice yourself reading a certain pattern of code over and over,
chances are a colleague could point to the bug at first glance.
From: Bruce Hoult
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <bruce-A1A7F1.00110706012006@news.clear.net.nz>
In article <·····················@lisp.de>,
 Rainer Joswig <······@lisp.de> wrote:

> > If you notice yourself writing a certain pattern of code over and over,
> > chances are it should be a macro.
> 
> If you notice yourself writing a certain pattern of code over and over,
> chances are it should be a function.

One I really hate, in Java is:

  if (debug)
    debug(turn_data_into_a_string_in_a_really_expensive_way);

Sure, there are a lot of places where it wouldnt' hurt much to turn that 
into a function.  But there are also a *lot* of places where that would 
make the code five or ten times slower than it needs to be when 
debugging is off.

-- 
Bruce |  41.1670S | \  spoken |          -+-
Hoult | 174.8263E | /\ here.  | ----------O----------
From: Pascal Costanza
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <424oq2F1gjjjoU1@individual.net>
Bruce Hoult wrote:
> In article <·····················@lisp.de>,
>  Rainer Joswig <······@lisp.de> wrote:
> 
>>>If you notice yourself writing a certain pattern of code over and over,
>>>chances are it should be a macro.
>>
>>If you notice yourself writing a certain pattern of code over and over,
>>chances are it should be a function.
> 
> One I really hate, in Java is:
> 
>   if (debug)
>     debug(turn_data_into_a_string_in_a_really_expensive_way);
> 
> Sure, there are a lot of places where it wouldnt' hurt much to turn that 
> into a function.  But there are also a *lot* of places where that would 
> make the code five or ten times slower than it needs to be when 
> debugging is off.

(defun log (string)
   (when *debug*
     (print string)))

(define-compiler-macro log (string)
   (when *debug*
     `(print ,string)))

...under the assumption that *debug* is supposed to be a compile-time 
flag. (It's probably a better idea to use symbol-macros instead of 
special variables for such flags, but I hope the idea is clear...)

It's a good idea to opt for the function/compiler-macro combination if 
something can be expressed as a function, because it allows you to still 
pass around a function as a first-class value and it makes it clearer 
that evaluation of arguments works as expected.


Pascal

-- 
My website: http://p-cos.net
Closer to MOP & ContextL:
http://common-lisp.net/project/closer/
From: ···············@yahoo.com
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <1136582079.289910.39220@g47g2000cwa.googlegroups.com>
 > if (debug)
 >   debug(turn_data_into_a_string_in_a_really_expensive_way);

If debug is final and is false at compile time, the whole thing is
omitted from the compiled code, isn't it?
From: Eli Gottlieb
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <wMAvf.87903$ME5.86686@twister.nyroc.rr.com>
Rainer Joswig wrote:
> Am 04.01.2006 20:56 Uhr schrieb "Eli Gottlieb" unter <···········@gmail.com>
> in ·····················@twister.nyroc.rr.com:
> 
> 
>>Majorinc wrote:
>>
>>>I've frequently read that macros are one of the most important
>>>strengths of Lisp, however, I do not understand why.
>>>
>>>Only advantage of Lisp macros over Lisp functions I see are
>>>slight increase of the speed and few quotes and perhaps
>>>arguments less. Not really much ...
>>>
>>>Am I missing something here?
>>>
>>
>>Macros return code.  Using them you can add new control constructs to
>>the language, or encapsulate entire algorithms, in addition to being
>>able to pass unevaluated arguments (ie: I can pass "(eval x)" to a macro
>>without it being evaluated).
>>
>>If you notice yourself writing a certain pattern of code over and over,
>>chances are it should be a macro.
> 
> 
> If you notice yourself writing a certain pattern of code over and over,
> chances are it should be a function.
> 
A repititious /pattern of code/ should be a macro.  A repititious 
/computation on multiple data sets/ should be a function.  You can often 
find yourself coding around the nonexistence of a particular language 
construct or template for a function.  That's where macros come in.
From: Rob Warnock
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <W_adnSqHxPtMnyDeRVn-uQ@speakeasy.net>
Majorinc, Kazimir  <·····@email.address> wrote:
+---------------
| I've frequently read that macros are one of the most important 
| strengths of Lisp, however, I do not understand why. 
...
| Am I missing something here? 
+---------------

Yes. Take a look at, say, HTOUT <http://www.cliki.net/htout> or
CL-WHO <http://www.cliki.net/CL-WHO>, both of which let you write
things like this:

    (let ((title "Simple Test Page"))
      (with-html-output (s *standard-output*)
	(:html
	  (:head (:title title)) (lfd)
	  ((:body :bgcolor "#d0d0ff")
	   (:h1 title) (lfd)
	   "This is a small demo table:" (lfd)
	   (:table (lfd)
	     (:tr (:th "i") (:th "2^i") (:th "10^i")) (lfd)
	     (loop for i below 5
		   for 2^i = (expt 2 i)
		   and 10^i = (expt 10 i) do
	       (htm (:tr (:td i) (:tr 2^i) (:tr 10^i))
		    (lfd))))))))

and get this output:

    <HTML><HEAD><TITLE>Simple Test Page</TITLE></HEAD>
    <BODY BGCOLOR='#d0d0ff'><H1>Simple Test Page</H1>
    This is a small demo table:
    <TABLE>
    <TR><TH>i</TH><TH>2^i</TH><TH>10^i</TH></TR>
    <TR><TD>0</TD><TR>1</TR><TR>1</TR></TR>
    <TR><TD>1</TD><TR>2</TR><TR>10</TR></TR>
    <TR><TD>2</TD><TR>4</TR><TR>100</TR></TR>
    <TR><TD>3</TD><TR>8</TR><TR>1000</TR></TR>
    <TR><TD>4</TD><TR>16</TR><TR>10000</TR></TR>
    </TABLE></BODY></HTML>

Yes, you can do HTML generation without macros, but it
tends to be ugly and full of deeply-nested LAMBDAs...


-Rob

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: Tiarnán Ó Corráin
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <m2k6debzm1.fsf@Cascade.local>
····@rpw3.org (Rob Warnock) writes:

> Yes. Take a look at, say, HTOUT <http://www.cliki.net/htout> or
> CL-WHO <http://www.cliki.net/CL-WHO>, both of which let you write
> things like this:
>
>     (let ((title "Simple Test Page"))
>       (with-html-output (s *standard-output*)
> 	(:html
> 	  (:head (:title title)) (lfd)
> 	  ((:body :bgcolor "#d0d0ff")
> 	   (:h1 title) (lfd)
> 	   "This is a small demo table:" (lfd)
> 	   (:table (lfd)
> 	     (:tr (:th "i") (:th "2^i") (:th "10^i")) (lfd)
> 	     (loop for i below 5
> 		   for 2^i = (expt 2 i)
> 		   and 10^i = (expt 10 i) do
> 	       (htm (:tr (:td i) (:tr 2^i) (:tr 10^i))
> 		    (lfd))))))))

And indeed, you can do something like:

(defmacro with-standard-page ((title &key (stylesheet "standard.css"))
                              &body body)
  `(with-html-output (s *standard-output*)
     (:html
      (:head (:title ,title)
	     (:link :rel "stylesheet" :href ,stylesheet))
      (:body
       (:h1 ,title)
       ,@body))))

and use it like:

(with-standard-page ("Simple test page")
  (:p "This is a small demo table:") 
  (:table 
   (:tr (:th "i") (:th "2^i") (:th "10^i"))
   (loop for i below 5
      for 2^i = (expt 2 i)
      and 10^i = (expt 10 i) do
      (htm (:tr (:td i) (:tr 2^i) (:tr 10^i))))))

-- 
Tiarn�n
From: Rainer Joswig
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <BFE2EDB3.24971%joswig@lisp.de>
Am 05.01.2006 13:58 Uhr schrieb "Tiarn�n � Corr�in" unter
<········@yahoo.com> in ··············@Cascade.local:

> ····@rpw3.org (Rob Warnock) writes:
> 
>> Yes. Take a look at, say, HTOUT <http://www.cliki.net/htout> or
>> CL-WHO <http://www.cliki.net/CL-WHO>, both of which let you write
>> things like this:
>> 
>>     (let ((title "Simple Test Page"))
>>       (with-html-output (s *standard-output*)
>> (:html
>>  (:head (:title title)) (lfd)
>>  ((:body :bgcolor "#d0d0ff")
>>   (:h1 title) (lfd)
>>   "This is a small demo table:" (lfd)
>>   (:table (lfd)
>>     (:tr (:th "i") (:th "2^i") (:th "10^i")) (lfd)
>>     (loop for i below 5
>>   for 2^i = (expt 2 i)
>>   and 10^i = (expt 10 i) do
>>       (htm (:tr (:td i) (:tr 2^i) (:tr 10^i))
>>    (lfd))))))))
> 
> And indeed, you can do something like:
> 
> (defmacro with-standard-page ((title &key (stylesheet "standard.css"))
>                               &body body)
>   `(with-html-output (s *standard-output*)
>      (:html
>       (:head (:title ,title)
>     (:link :rel "stylesheet" :href ,stylesheet))
>       (:body
>        (:h1 ,title)
>        ,@body))))
> 
> and use it like:
> 
> (with-standard-page ("Simple test page")
>   (:p "This is a small demo table:")
>   (:table 
>    (:tr (:th "i") (:th "2^i") (:th "10^i"))
>    (loop for i below 5
>       for 2^i = (expt 2 i)
>       and 10^i = (expt 10 i) do
>       (htm (:tr (:td i) (:tr 2^i) (:tr 10^i))))))

Why would you write it as a macro? This has only disadvantages.

That's exactly the place where I would NOT use macros. Where macros even
are EVIL.

I'm using functions for it.

(defun generate-benchmark-page (url stream)
  (generate-basic-page
   url stream
   :render-function (lambda (url stream)
                      (declare (ignore url))
                      (render-benchmark-table
                       (list *benchmark-values* *benchmark1-values*
                             *benchmark2-values* *benchmark3-values*
                             *benchmark4-values*)
                       stream
                       :table-type :horizontal))
   :title "Rainer Joswig's Home, Lisp Benchmarks"))


Functions are easier to debug.
- you can see the function call on the stack
- the stack you see and the source code have some similarity
- you can trace functions
- you can set break points on functions

Functions are easier to change.
- functions can be changed and as long as the interface is still valid, you
don't have to change the caller
- you usually only have to recompile the function and not all callers

Functions don't duplicate the code all over the place and so on.
- functions usually don't inline all the code

Functions are easier to reuse.
- since functions itself are first-class objects, you can store them, pass
them around, or return them from functions
- you can combine environments and functions to closures, these are also
first class objects


First basic Lisp rule:  Use 'late binding' to your advantage.



Alan Kay about 'late binding':

---

A Bit About Late Binding From Alan Kay

Thanks Alan!

    Most software is made by programmers creating text files that are fed to
a compiler and loader which makes a runable program. One can tell how early-
or late-bound a system is by looking at the things that can be changed while
the program is running. For example, it is generally true of C based systems
that most changes in the program have to be done by going back to the text
files, changing them, and recompiling and loading them. This is even true of
Java. Organizationally, this often leads to at most one or two system builds
a day before most bugs can be found.

    A late-bound system like LISP or Smalltalk can change pretty much
everything while it is running -- in fact, both these systems are so good at
this that their development systems are written in themselves and are active
during runtime. For example, a program change in Smalltalk takes less than a
second to take effect, thus many more bugs can be run down and fixed.

    But late-bound has some deeper and more profound properties that include
abilities to actually change the both the structure and metastructure of the
language itself. Thus an important new idea can be assimilated into the
constantly evolving process that is the system.

    Another aspect of late-binding is the ability to change one's mind about
already instantiated structures that are already doing work. These can be
changed automatically on the fly without harming the work they are already
doing.

    Etc. Wheels within wheels.

    These ideas are not new, but they are quite foreign and out of the scope
of the way most programming is done today. -- Alan Kay.


---
From: Tiarnán Ó Corráin
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <m27j9eb5p5.fsf@Cascade.local>
Rainer Joswig <······@lisp.de> writes:

> Am 05.01.2006 13:58 Uhr schrieb "Tiarn�n � Corr�in" unter
> <········@yahoo.com> in ··············@Cascade.local:
>> (with-standard-page ("Simple test page")
>>   (:p "This is a small demo table:")
>>   (:table 
>>    (:tr (:th "i") (:th "2^i") (:th "10^i"))
>>    (loop for i below 5
>>       for 2^i = (expt 2 i)
>>       and 10^i = (expt 10 i) do
>>       (htm (:tr (:td i) (:tr 2^i) (:tr 10^i))))))
>
> Why would you write it as a macro? This has only disadvantages.

I'm not so sure, but am willing to be persuaded. For me, the advantage
is that with a macro I can start writing sexp'd HTML without any of
the "with-html-output" sort of cruft. 

It is, in fact, one of the fundamental uses of macros, to create a
lexical context for what is in effect a domain language.

> That's exactly the place where I would NOT use macros. Where macros even
> are EVIL.

Phew! Thermostat must be broken...

-- 
Tiarn�n
From: Rainer Joswig
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <joswig-25DCED.01092006012006@news-europe.giganews.com>
In article <··············@Cascade.local>,
 ········@yahoo.com (Tiarn�n � Corr�in) wrote:

> Rainer Joswig <······@lisp.de> writes:
> 
> > Am 05.01.2006 13:58 Uhr schrieb "Tiarn�n � Corr�in" unter
> > <········@yahoo.com> in ··············@Cascade.local:
> >> (with-standard-page ("Simple test page")
> >>   (:p "This is a small demo table:")
> >>   (:table 
> >>    (:tr (:th "i") (:th "2^i") (:th "10^i"))
> >>    (loop for i below 5
> >>       for 2^i = (expt 2 i)
> >>       and 10^i = (expt 10 i) do
> >>       (htm (:tr (:td i) (:tr 2^i) (:tr 10^i))))))
> >
> > Why would you write it as a macro? This has only disadvantages.
> 
> I'm not so sure, but am willing to be persuaded. For me, the advantage
> is that with a macro I can start writing sexp'd HTML without any of
> the "with-html-output" sort of cruft. 

I would write something like this:

(defun render-my-page (stream)
  (render-standard-page
    :stream stream
    :title "Simple test Page"
    :renderer (create-sexpd-html-render-function stream
                 (:p ....


The page building blocks then are functions that can
be combined, reused, traced, debugged, ....

You can also build a library of first-class render functions.
Store them, pass them around, call them.


Just one macro where it is needed. Where the
special language is used:

So instead of:

Macro with-standard-page
Macro with-non-standard-page
Macro with-almost-standard-page
Macro with-less-than-standard-page

-> 4 non-functional macros. Little reuse.


Better:

Macro      with-sexpd-html
Function   render-standard-page
Function   render-non-standard-page
Function   render-almost-standard-page
Function   render-less-than-standard-page

-> 1 non-functional macro. four new reusable building blocks.
-> more reusable software, better debuggable., better maintainable


> It is, in fact, one of the fundamental uses of macros, to create a
> lexical context for what is in effect a domain language.
> 
> > That's exactly the place where I would NOT use macros. Where macros even
> > are EVIL.
> 
> Phew! Thermostat must be broken...


No, you will just write less maintainable software.
I think overuse of macros is really bad practice. People
think it's cool, but it is not. If you were ever in the situation
to maintain software writte by people who overuse macros
you may understand what I mean.

I once helped a guy to debug his software, where he was trying to
write macros that generated macro generating code. He was lost.
Really lost.

For me there are a few signs people are doing the wrong thing.
Some of these signs:

- use of EVAL
- use of macros
- use of APPEND
- use of SET and SETF at the top-level
- use of lots of special variables
- use of idioms like   (do-it 'some-op foo bar)
- using foo::bar

and more...

-- 
http://lispm.dyndns.org/
From: Creighton Hogg
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <Pine.LNX.4.58.0601051810320.5872@login01.hep.wisc.edu>
On Fri, 6 Jan 2006, Rainer Joswig wrote:
<>
> I think overuse of macros is really bad practice. People
> think it's cool, but it is not. If you were ever in the situation
> to maintain software writte by people who overuse macros
> you may understand what I mean.
> 
> I once helped a guy to debug his software, where he was trying to
> write macros that generated macro generating code. He was lost.
> Really lost.
> 
> For me there are a few signs people are doing the wrong thing.
> Some of these signs:
> 
> - use of EVAL
> - use of macros
> - use of APPEND
> - use of SET and SETF at the top-level
> - use of lots of special variables
> - use of idioms like   (do-it 'some-op foo bar)
> - using foo::bar
> 
> and more...

Hrmm...I'm curious then.  So you are saying that while 
macros are an important tool in lisp programming, that they 
are the "big-guns" and needn't be pulled out too often?
I'm figuring that you are not arguing against macros in 
general, because if that was the case why use CL instead of 
haskell or ruby or <fill in the blank>.
From: Rainer Joswig
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <joswig-42FEE5.01323406012006@news-europe.giganews.com>
In article <································@login01.hep.wisc.edu>,
 Creighton Hogg <······@login01.hep.wisc.edu> wrote:

> On Fri, 6 Jan 2006, Rainer Joswig wrote:
> <>
> > I think overuse of macros is really bad practice. People
> > think it's cool, but it is not. If you were ever in the situation
> > to maintain software writte by people who overuse macros
> > you may understand what I mean.
> > 
> > I once helped a guy to debug his software, where he was trying to
> > write macros that generated macro generating code. He was lost.
> > Really lost.
> > 
> > For me there are a few signs people are doing the wrong thing.
> > Some of these signs:
> > 
> > - use of EVAL
> > - use of macros
> > - use of APPEND
> > - use of SET and SETF at the top-level
> > - use of lots of special variables
> > - use of idioms like   (do-it 'some-op foo bar)
> > - using foo::bar
> > 
> > and more...
> 
> Hrmm...I'm curious then.  So you are saying that while 
> macros are an important tool in lisp programming, that they 
> are the "big-guns" and needn't be pulled out too often?
> I'm figuring that you are not arguing against macros in 
> general, because if that was the case why use CL instead of 
> haskell or ruby or <fill in the blank>.

Macros are just ONE feature of CL. Useful, but in controlled
surroundings.

CL macros are of a certain kind. They are procedural
macros. That gives you a lot of freedom. To shoot you into
your foot. Plus they are macros. This has lots of
disadvantages for coding maintainable software.
But there is some good use for it.

CL is more than Ruby + Macros, Haskell + Macros, or X + Macros.

CL is a pragmatic blend of several programming facilities
from the Lisp history.

CL is a dynamic programming language.
CL is a functional programming language.
CL is a procedural programming language.
CL is a compilation supporting programming language.
CL is a interactive programming language.
CL is a incrementally extendable programming language.
CL is a reflective programming language.
CL is a symbolic programming language.
CL is a object-oriented programming language.
CL is a standardized programming language.
CL is a programmable programming language.
CL is a late-binding programming language.


And some more.

All these different natures of Lisp are blended into
one ugly, compromised, ill-defined, aging, stagnating,
hated, loved, laughed-about, pointed-at dialect called
Common Lisp.

Still, I like it. ;-)

-- 
http://lispm.dyndns.org/
From: Creighton Hogg
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <Pine.LNX.4.58.0601051906510.5872@login01.hep.wisc.edu>
On Fri, 6 Jan 2006, Rainer Joswig wrote:
<>
> Macros are just ONE feature of CL. Useful, but in controlled
> surroundings.
> 
> CL macros are of a certain kind. They are procedural
> macros. That gives you a lot of freedom. To shoot you into
> your foot. Plus they are macros. This has lots of
> disadvantages for coding maintainable software.
> But there is some good use for it.
> 
> CL is more than Ruby + Macros, Haskell + Macros, or X + Macros.
> 
> CL is a pragmatic blend of several programming facilities
> from the Lisp history.
> 
> CL is a dynamic programming language.
> CL is a functional programming language.
> CL is a procedural programming language.
> CL is a compilation supporting programming language.
> CL is a interactive programming language.
> CL is a incrementally extendable programming language.
> CL is a reflective programming language.
> CL is a symbolic programming language.
> CL is a object-oriented programming language.
> CL is a standardized programming language.
> CL is a programmable programming language.
> CL is a late-binding programming language.
> 
> 
> And some more.
> 
> All these different natures of Lisp are blended into
> one ugly, compromised, ill-defined, aging, stagnating,
> hated, loved, laughed-about, pointed-at dialect called
> Common Lisp.
> 
> Still, I like it. ;-)

An interesting answer.
I liked it.
From: Tiarnán Ó Corráin
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <m2psn69oec.fsf@Cascade.local>
Rainer Joswig <······@lisp.de> writes:

> I would write something like this:
>
> (defun render-my-page (stream)
>   (render-standard-page
>     :stream stream
>     :title "Simple test Page"
>     :renderer (create-sexpd-html-render-function stream
>                  (:p ....

Ok, but I don't see a significant difference.

> The page building blocks then are functions that can
> be combined, reused, traced, debugged, ....

The macro can also be used, and macroexpanded, which might be better
than tracing in some situations (ie building HTML pages)

> You can also build a library of first-class render functions.
> Store them, pass them around, call them.

I have a library of first-class render methods, most of which call
with-std-page macro. I'm still not sure what having with-std-page as a
function saves me.

Usually along the lines of:

(defmethod render ((obj foo))
  (with-std-page ((name foo)
		  :leftsidebar (cross-refs foo)
		  :rightsidebar (links foo))
    (...sexpr/html stuff...)))

> For me there are a few signs people are doing the wrong thing.
> Some of these signs:
>
> - use of EVAL

Agreed.

> - use of macros

I can't agree... overuse of macros, perhaps.

> - use of APPEND

I'm mystified by this: could you explain?

> - use of SET and SETF at the top-level
> - use of lots of special variables
> - use of idioms like   (do-it 'some-op foo bar)
> - using foo::bar

Absolutely.

-- 
Tiarn�n
From: Tiarnán Ó Corráin
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <m2hd8i9o3x.fsf@Cascade.local>
········@yahoo.com (Tiarn�n � Corr�in) writes:

> The macro can also be used, and macroexpanded, which might be better
-----------------------^re
From: Rainer Joswig
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <BFE382CB.24A60%joswig@lisp.de>
> Von: Tiarn�n � Corr�in <········@yahoo.com>
> Organisation: Eircom.Net http://www.eircom.net
> Newsgroups: comp.lang.lisp
> Datum: Fri, 06 Jan 2006 00:43:39 +0000
> Betreff: Re: What is the main advantage of macros over functions?
> 
> Rainer Joswig <······@lisp.de> writes:
> 
>> I would write something like this:
>> 
>> (defun render-my-page (stream)
>>   (render-standard-page
>>     :stream stream
>>     :title "Simple test Page"
>>     :renderer (create-sexpd-html-render-function stream
>>                  (:p ....
> 
> Ok, but I don't see a significant difference.
> 
>> The page building blocks then are functions that can
>> be combined, reused, traced, debugged, ....
> 
> The macro can also be used, and macroexpanded, which might be better
> than tracing in some situations (ie building HTML pages)

Really? I usually write some generator functions and then I run it
and inspect the output. If I need to look closer, I use a debugger
or even a stepper.
 
>> You can also build a library of first-class render functions.
>> Store them, pass them around, call them.
> 
> I have a library of first-class render methods, most of which call
> with-std-page macro. I'm still not sure what having with-std-page as a
> function saves me.

WITH-STD-PAGE as a macro is the wrong abstraction. It does several different
things where a macro is not needed. If the only thing you need a macro,
is where you introduce the HTML sexp syntax, then I would name it like
that and reduce it to exactly that purpose - providing the syntactic
extension. 

> 
> Usually along the lines of:
> 
> (defmethod render ((obj foo))
>   (with-std-page ((name foo)
>  :leftsidebar (cross-refs foo)
>  :rightsidebar (links foo))
>     (...sexpr/html stuff...)))
> 
>> For me there are a few signs people are doing the wrong thing.
>> Some of these signs:
>> 
>> - use of EVAL
> 
> Agreed.
> 
>> - use of macros
> 
> I can't agree... overuse of macros, perhaps.
> 
>> - use of APPEND
> 
> I'm mystified by this: could you explain?

Oh, see code snippets like this:

(let ((list some-list))
  (dolist (item some-other-list)
    (setf list (append list (list item))))
  list)

> 
>> - use of SET and SETF at the top-level
>> - use of lots of special variables
>> - use of idioms like   (do-it 'some-op foo bar)
>> - using foo::bar
> 
> Absolutely.
> 
> -- 
> Tiarn�n
From: Philippe Lorin
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <43be63a3$0$21734$626a14ce@news.free.fr>
Rainer Joswig wrote:
> Oh, see code snippets like this:
> 
> (let ((list some-list))
>   (dolist (item some-other-list)
>     (setf list (append list (list item))))
>   list)

I find myself writing this all too often. I can feel it's ugly, but I 
don't know a better way, and I must admit I was too ashamed to ask. Now, 
as you've brought up the topic, what's the better way?
From: André Thieme
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <1136551749.584378.14160@g49g2000cwa.googlegroups.com>
Philippe Lorin schrieb:

> Rainer Joswig wrote:
> > Oh, see code snippets like this:
> >
> > (let ((list some-list))
> >   (dolist (item some-other-list)
> >     (setf list (append list (list item))))
> >   list)
>
> I find myself writing this all too often. I can feel it's ugly, but I
> don't know a better way, and I must admit I was too ashamed to ask. Now,
> as you've brought up the topic, what's the better way?

Instead of the code Rainer posted you could say:
(append some-list some-other-list)


André
--
From: Edi Weitz
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <uzmm9h6a3.fsf@agharta.de>
On Fri, 06 Jan 2006 13:34:02 +0100, Philippe Lorin <············@gmail.com> wrote:

> Rainer Joswig wrote:
>> Oh, see code snippets like this:
>> (let ((list some-list))
>>   (dolist (item some-other-list)
>>     (setf list (append list (list item))))
>>   list)
>
> I find myself writing this all too often. I can feel it's ugly, but
> I don't know a better way, and I must admit I was too ashamed to
> ask. Now, as you've brought up the topic, what's the better way?

What about (SETF LIST (APPEND SOME-LIST SOME-OTHER-LIST))?  Still uses
APPEND but if you want to /append/ one list to another one I think
it's perfectly legitimate to use APPEND.

OTOH, if you find yourself using APPEND in a loop where you're
constantly adding something to the end of a list you're probably doing
something wrong.  Try adding to the front of the list with PUSH or
CONS and finally reverse the result with REVERSE and NREVERSE.

Or use LOOP with COLLECT or APPEND/NCONC which does that for you.

Or check out rare stuff like REVAPPEND and NRECONC... :)

Cheers,
Edi.

-- 

Lisp is not dead, it just smells funny.

Real email: (replace (subseq ·········@agharta.de" 5) "edi")
From: Rainer Joswig
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <BFE42787.24B17%joswig@lisp.de>
Am 06.01.2006 13:34 Uhr schrieb "Philippe Lorin" unter
<············@gmail.com> in ·························@news.free.fr:

> Rainer Joswig wrote:
>> Oh, see code snippets like this:
>> 
>> (let ((list some-list))
>>   (dolist (item some-other-list)
>>     (setf list (append list (list item))))
>>   list)
> 
> I find myself writing this all too often. I can feel it's ugly, but I
> don't know a better way, and I must admit I was too ashamed to ask. Now,
> as you've brought up the topic, what's the better way?

Good that you asked. ;-)

Do you see the problem? The problem is that appending an item at the end of
a list is an inefficient operation. It also conses a new list every time.

(append *extremely-long-list* (list 1))   copies the extremely long list
and then just appends one item. If you do this in a loop or via recursion,
this adds up very quickly.

So a typical solution would be to cons the second list once and then
do one append operation.

Another would be cons a new list (if necessary) and modify the tail
destructively. Or even reuse the original list.

Sometimes it might also be possible to add the items to the head (which is
cheaper) and then reverse the list once.

And so on...
From: Giorgos Keramidas
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <864q4fh6zy.fsf@flame.pc>
On Fri, 06 Jan 2006 13:34:02 +0100,
Philippe Lorin <············@gmail.com> wrote:
> Rainer Joswig wrote:
>> Oh, see code snippets like this:
>> (let ((list some-list))
>>   (dolist (item some-other-list)
>>     (setf list (append list (list item))))
>>   list)
>
> I find myself writing this all too often. I can feel it's ugly, but I
> don't know a better way, and I must admit I was too ashamed to ask. Now,
> as you've brought up the topic, what's the better way?

I'm only beginning to learn LISP myself too, but it's clear that
appending again and again in a loop is terrible.  It may have to
traverse the resulting list once for every item appended, which will
take an absurdly long amount of time for something as simple as:

    (append some-list some-other-list)

If processing is involved, but only for the elements of some-list, I'd
probably write this as:

    (append (loop for x in some-list
                  collect (foo x))
	    some-other-list)

If processing is required for some-other-list only:

    (append some-list
            (loop for x in some-other
                  collect (foo x)))

If you want to write this without (loop), I believe the best thing to do
would be to use (nreverse):

    ; Process only the elements of the second list part
    (append some-list
	    (let ((result-list nil))
	      (dolist (item some-other-list)
                (setf result-list (cons (foo x) result-list)))
	      (nreverse result-list)))

    ; Process only the elements of the first list part
    (append (let ((result-list nil))
              (dolist (item some-list)
                (setf result-list (cons (foo x) result-list)))
              (nreverse result-list))
	    some-other-list)
From: Pascal Bourguignon
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <87k6dbxzue.fsf@thalassa.informatimago.com>
Giorgos Keramidas <········@ceid.upatras.gr> writes:

> If processing is involved, but only for the elements of some-list, I'd
> probably write this as:
>
>     (append (loop for x in some-list
>                   collect (foo x))
> 	    some-other-list)

Since loop collect builds a new list, you can use nconc here.

     (nconc (loop for x in some-list collect (foo x)) some-other-list)

> If processing is required for some-other-list only:
>
>     (append some-list
>             (loop for x in some-other
>                   collect (foo x)))

idem.

> If you want to write this without (loop), I believe the best thing to do
> would be to use (nreverse):
>
>     ; Process only the elements of the second list part
>     (append some-list
> 	    (let ((result-list nil))
> 	      (dolist (item some-other-list)
>                 (setf result-list (cons (foo x) result-list)))
> 	      (nreverse result-list)))

idem.

>     ; Process only the elements of the first list part
>     (append (let ((result-list nil))
>               (dolist (item some-list)
>                 (setf result-list (cons (foo x) result-list)))
>               (nreverse result-list))
> 	    some-other-list)

idem.

Conclusion: never use APPEND, use NCONC! (in your examples).


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

"Our users will know fear and cower before our software! Ship it!
Ship it and let them flee like the dogs they are!"
From: Giorgos Keramidas
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <86slrzfovv.fsf@flame.pc>
Pascal Bourguignon <····@mouse-potato.com> wrote:
> Giorgos Keramidas <········@ceid.upatras.gr> writes:
>> If processing is involved, but only for the elements of some-list, I'd
>> probably write this as:
>>
>>     (append (loop for x in some-list
>>                   collect (foo x))
>> 	    some-other-list)
>
> Since loop collect builds a new list, you can use nconc here.
>
>      (nconc (loop for x in some-list collect (foo x)) some-other-list)
>
>> If processing is required for some-other-list only:
>>
>>     (append some-list
>>             (loop for x in some-other
>>                   collect (foo x)))
>
> idem.
>
>> If you want to write this without (loop), I believe the best thing to do
>> would be to use (nreverse):
>>
>>     ; Process only the elements of the second list part
>>     (append some-list
>> 	    (let ((result-list nil))
>> 	      (dolist (item some-other-list)
>>                 (setf result-list (cons (foo x) result-list)))
>> 	      (nreverse result-list)))
>
> idem.
>
>>     ; Process only the elements of the first list part
>>     (append (let ((result-list nil))
>>               (dolist (item some-list)
>>                 (setf result-list (cons (foo x) result-list)))
>>               (nreverse result-list))
>> 	    some-other-list)
>
> idem.
>
> Conclusion: never use APPEND, use NCONC! (in your examples).

Very right, of course.

I admit that I was a bit puzzled when I read Peter Seibel's advice that
NCONC is one of the few exceptions of recycling/destructive operations
whose side-effecst *can* be relied upon and are actually useful in some
cases.

Now I know when, too :)  Many thanks
From: Thomas A. Russ
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <ymi64otibhk.fsf@sevak.isi.edu>
Pascal Bourguignon <····@mouse-potato.com> writes:

> 
> Giorgos Keramidas <········@ceid.upatras.gr> writes:
> 
> > If processing is involved, but only for the elements of some-list, I'd
> > probably write this as:
> >
> >     (append (loop for x in some-list
> >                   collect (foo x))
> > 	    some-other-list)
> 
> Since loop collect builds a new list, you can use nconc here.
> 
>      (nconc (loop for x in some-list collect (foo x)) some-other-list)
> 
> > If processing is required for some-other-list only:
> >
> >     (append some-list
> >             (loop for x in some-other
> >                   collect (foo x)))
> 
> idem.

Sorry, no.  Using NCONC on "some-list" might not be safe, since it isn't
new list structure.

-- 
Thomas A. Russ,  USC/Information Sciences Institute
From: Pascal Bourguignon
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <87psn19mmv.fsf@thalassa.informatimago.com>
···@sevak.isi.edu (Thomas A. Russ) writes:

> Pascal Bourguignon <····@mouse-potato.com> writes:
>
>> 
>> Giorgos Keramidas <········@ceid.upatras.gr> writes:
>> 
>> > If processing is involved, but only for the elements of some-list, I'd
>> > probably write this as:
>> >
>> >     (append (loop for x in some-list
>> >                   collect (foo x))
>> > 	    some-other-list)
>> 
>> Since loop collect builds a new list, you can use nconc here.
>> 
>>      (nconc (loop for x in some-list collect (foo x)) some-other-list)
>> 
>> > If processing is required for some-other-list only:
>> >
>> >     (append some-list
>> >             (loop for x in some-other
>> >                   collect (foo x)))
>> 
>> idem.
>
> Sorry, no.  Using NCONC on "some-list" might not be safe, since it isn't
> new list structure.

Right. I've been too quick on this last idem. Sorry for the confusion.

-- 
__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: John Thingstad
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <op.s21hm1mfpqzri1@mjolner.upc.no>
On Sun, 08 Jan 2006 01:56:49 +0100, Giorgos Keramidas  
<········@ceid.upatras.gr> wrote:

>
> If you want to write this without (loop), I believe the best thing to do
> would be to use (nreverse):
>
>     ; Process only the elements of the second list part
>     (append some-list
> 	    (let ((result-list nil))
> 	      (dolist (item some-other-list)
>                 (setf result-list (cons (foo x) result-list)))
> 	      (nreverse result-list)))
>
>     ; Process only the elements of the first list part
>     (append (let ((result-list nil))
>               (dolist (item some-list)
>                 (setf result-list (cons (foo x) result-list)))
>               (nreverse result-list))
> 	    some-other-list)
>

I would use (push (foo x) result-list) here.
(Pascal covered nconc)

-- 
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
From: Coby Beck
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <%ikvf.30105$km.7093@edtnps89>
"Rainer Joswig" <······@lisp.de> wrote in message 
·································@news-europe.giganews.com...

> I think overuse of macros is really bad practice. People
> think it's cool, but it is not. If you were ever in the situation
> to maintain software writte by people who overuse macros
> you may understand what I mean.

This applies to *misuse* of macros, of which overuse is a small subset.  In 
fact I don't understand how one can overuse macros except through misuse. 
Macros are *no different* from any other tool in this respect, they are only 
a bit more subtle to really understand.

> I once helped a guy to debug his software, where he was trying to
> write macros that generated macro generating code. He was lost.
> Really lost.

Misuse.

> For me there are a few signs people are doing the wrong thing.
> Some of these signs:
>
> - use of EVAL
> - use of macros
> - use of APPEND
> - use of SET and SETF at the top-level
> - use of lots of special variables
> - use of idioms like   (do-it 'some-op foo bar)
> - using foo::bar

No way, no how do macros or append belong in there.  I agree that the others 
are signs of possible bad design, though they sometimes (on rare occasions 
as one moves about in RL) just indicate an unusual problem.

-- 
Coby Beck
(remove #\Space "coby 101 @ bigpond . com")
From: Timofei Shatrov
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <43be35ca.6448555@news.readfreenews.net>
On Fri, 06 Jan 2006 01:09:20 +0100, Rainer Joswig <······@lisp.de> tried
to confuse everyone with this message:


>- use of idioms like   (do-it 'some-op foo bar)

Is it a potshot at ASDF? I also find (asdf:oos 'asdf:load-op :blabla)
one of the most annoying things to type ever.

-- 
|a\o/r|,-------------.,---------- Timofei Shatrov aka Grue ------------.
| m"a ||FC AMKAR PERM|| mail: grue at mail.ru  http://grue3.tripod.com |
|  k  ||  PWNZ J00   || Kingdom of Loathing: Grue3 lvl 18 Seal Clubber |
`-----'`-------------'`-------------------------------------------[4*72]
From: justinhj
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <1136562017.591118.325330@g49g2000cwa.googlegroups.com>
Timofei Shatrov wrote:
> On Fri, 06 Jan 2006 01:09:20 +0100, Rainer Joswig <······@lisp.de> tried
> to confuse everyone with this message:
>
>
> >- use of idioms like   (do-it 'some-op foo bar)
>
> Is it a potshot at ASDF? I also find (asdf:oos 'asdf:load-op :blabla)
> one of the most annoying things to type ever.
>
> --
> |a\o/r|,-------------.,---------- Timofei Shatrov aka Grue ------------.
> | m"a ||FC AMKAR PERM|| mail: grue at mail.ru  http://grue3.tripod.com |
> |  k  ||  PWNZ J00   || Kingdom of Loathing: Grue3 lvl 18 Seal Clubber |
> `-----'`-------------'`-------------------------------------------[4*72]

I agree. I keep a little list file with the load and install commands
along with the load for some of the packages i use. Then I just go in
and eval the ones i want, so I don't need to type that. You could also
wrap it up in cleaner code with little effort.
From: Thomas F. Burdick
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <xcvk6dbklqm.fsf@conquest.OCF.Berkeley.EDU>
"justinhj" <········@gmail.com> writes:

> Timofei Shatrov wrote:
> > On Fri, 06 Jan 2006 01:09:20 +0100, Rainer Joswig <······@lisp.de> tried
> > to confuse everyone with this message:
> >
> >
> > >- use of idioms like   (do-it 'some-op foo bar)
> >
> > Is it a potshot at ASDF? I also find (asdf:oos 'asdf:load-op :blabla)
> > one of the most annoying things to type ever.

I would guess that Rainer was referring to implementations of do-it
that simply dispatch on the first argument.  In the case of asdf,
asdf:operate instantiates the class you give it, and proceeds to use
it as an important argument in quite a number of generic functions
whose methods put double-dispatch to good use.

One of asdf's purposes was to be a defsystem that's written in
portable ANSI Common Lisp, so using the MOP wouldn't be an option
here.  If it were, I suppose asdf:operation could be a subclass of
FUNCALLABLE-STANDARD-CLASS and all of what are now generic functions
could be specializers of a really weird method combination.  That
doesn't sound at all like a win to me, from a maintainability perspective.

> I agree. I keep a little list file with the load and install commands
> along with the load for some of the packages i use. Then I just go in
> and eval the ones i want, so I don't need to type that. You could also
> wrap it up in cleaner code with little effort.

I would have thought that SLIME makes this a non-issue now.  If you
type ",load-system" you get a nice front-end to ASDF, complete with
SLIME handling the compilation noise.

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | Free Mumia Abu-Jamal! |
     ,--'    _,'   | Abolish the racist    |
    /       /      | death penalty!        |
   (   -.  |       `-----------------------'
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Rainer Joswig
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <joswig-55A711.10441406012006@news-europe.giganews.com>
In article <················@news.readfreenews.net>,
 ····@mail.ru (Timofei Shatrov) wrote:

> On Fri, 06 Jan 2006 01:09:20 +0100, Rainer Joswig <······@lisp.de> tried
> to confuse everyone with this message:
> 
> 
> >- use of idioms like   (do-it 'some-op foo bar)
> 
> Is it a potshot at ASDF? I also find (asdf:oos 'asdf:load-op :blabla)
> one of the most annoying things to type ever.

Hmm, I don't use ASDF, so I cannot say much about it.


Well, it is similar to the ancient SEND function in earlier
OOP substrates.

(send object message-name &rest arguments)  of Flavors
has long been replaced by

(function object1 ... objectn)  in CLOS.



also if DO-IT is similar to FUNCALL you would have

(FUNCALL 'some-op foo bar)

which also can better be written

(some-op foo bar)


Typically it is useful to try to stick with the built-in
mechanisms for calling functions. If they aren't sufficient,
one might try to use Generic Functions. If those are not
sufficient, you can write method combinations for
generic functions.

I'd say inventing new calling schemes is surely fun, but
one might need a real reason to force others to use them.

-- 
http://lispm.dyndns.org/
From: Rob Warnock
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <PJadnYvBstk88iPeRVn-rg@speakeasy.net>
Rainer Joswig  <······@lisp.de> wrote:
+---------------
| <········@yahoo.com> in ··············@Cascade.local:
| > ····@rpw3.org (Rob Warnock) writes:
| >> (let ((title "Simple Test Page"))
| >>   (with-html-output (s *standard-output*)
| >>     (:html
| >>       (:head (:title title)) (lfd)
...
| > And indeed, you can do something like:
| > (defmacro with-standard-page ((title &key (stylesheet "standard.css"))
| >                               &body body)
...
| 
| Why would you write it as a macro? This has only disadvantages.
| That's exactly the place where I would NOT use macros. Where macros even
| are EVIL.
| I'm using functions for it.
| 
| (defun generate-benchmark-page (url stream)
|   (generate-basic-page
|    url stream
|    :render-function (lambda (url stream)
|                       (declare (ignore url))
|                       (render-benchmark-table
|                        (list *benchmark-values* *benchmark1-values*
|                              *benchmark2-values* *benchmark3-values*
|                              *benchmark4-values*)
|                        stream
|                        :table-type :horizontal))
|    :title "Rainer Joswig's Home, Lisp Benchmarks"))
+---------------

O.k., you caught me. I don't actually use macros for "wrapper" pages
either. The RESULTS-TEMPLATE-PAGE I mentioned in an earlier reply is
actually a function, that takes a LAMBDA or oter function as a callback.

You're right, such functions are less code-wasteful, and easier to
debug.

But WITH-HTML-OUTPUT... that one *should* be a macro!


-Rob

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: Rainer Joswig
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <joswig-8DC194.14333806012006@news-europe.giganews.com>
In article <······················@speakeasy.net>,
 ····@rpw3.org (Rob Warnock) wrote:

> Rainer Joswig  <······@lisp.de> wrote:
> +---------------
> | <········@yahoo.com> in ··············@Cascade.local:
> | > ····@rpw3.org (Rob Warnock) writes:
> | >> (let ((title "Simple Test Page"))
> | >>   (with-html-output (s *standard-output*)
> | >>     (:html
> | >>       (:head (:title title)) (lfd)
> ...
> | > And indeed, you can do something like:
> | > (defmacro with-standard-page ((title &key (stylesheet "standard.css"))
> | >                               &body body)
> ...
> | 
> | Why would you write it as a macro? This has only disadvantages.
> | That's exactly the place where I would NOT use macros. Where macros even
> | are EVIL.
> | I'm using functions for it.
> | 
> | (defun generate-benchmark-page (url stream)
> |   (generate-basic-page
> |    url stream
> |    :render-function (lambda (url stream)
> |                       (declare (ignore url))
> |                       (render-benchmark-table
> |                        (list *benchmark-values* *benchmark1-values*
> |                              *benchmark2-values* *benchmark3-values*
> |                              *benchmark4-values*)
> |                        stream
> |                        :table-type :horizontal))
> |    :title "Rainer Joswig's Home, Lisp Benchmarks"))
> +---------------
> 
> O.k., you caught me. I don't actually use macros for "wrapper" pages
> either. The RESULTS-TEMPLATE-PAGE I mentioned in an earlier reply is
> actually a function, that takes a LAMBDA or oter function as a callback.
> 
> You're right, such functions are less code-wasteful, and easier to
> debug.
> 
> But WITH-HTML-OUTPUT... that one *should* be a macro!

Fine with me. ;-) If you don't tell anybody that CL-HTTP is
full of macrology. ;-)

> 
> 
> -Rob
> 
> -----
> Rob Warnock			<····@rpw3.org>
> 627 26th Avenue			<URL:http://rpw3.org/>
> San Mateo, CA 94403		(650)572-2607

-- 
http://lispm.dyndns.org/
From: Rob Warnock
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <PJadnYjBstn78yPeRVn-rg@speakeasy.net>
Tiarn�n � Corr�in <········@yahoo.com> wrote:
+---------------
| ····@rpw3.org (Rob Warnock) writes:
| > Yes. Take a look at, say, HTOUT <http://www.cliki.net/htout> or
| > CL-WHO <http://www.cliki.net/CL-WHO>, both of which let you write
| > things like this:
| > (let ((title "Simple Test Page"))
| >   (with-html-output (s *standard-output*)
| > 	(:html
| > 	  (:head (:title title)) (lfd)
...
| 
| And indeed, you can do something like:
| (defmacro with-standard-page ((title &key (stylesheet "standard.css"))
|                               &body body)
+---------------

And indeed, when I'm actually doing a web site with it [as opposed
to a quicky c.l.lisp "why use macros" example], I do things like that,
of course. I have macros & functions with names like these:

    results-template-page
    sql-error-page
    emit-top-toolbar
    emit-addnew-button
    decode-image-button-name
    build-continuation		; for multi-step form dialogs
    emit-editbox-list
    make-mailto-link

and so on...


-Rob

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: Ulrich Hobelmann
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <424hodF1hhbhbU1@individual.net>
Rob Warnock wrote:
> Yes, you can do HTML generation without macros, but it
> tends to be ugly and full of deeply-nested LAMBDAs...

Yes, it's to choose between Lisp and concise elegance, or ugly PHP or 
Java template engine / Apache project hell (study ten different complex 
frameworks before you can get anything done; any change needs at least 
five XML files to be edited; error discovery methods are nonexistent).

-- 
the bottom line is that a JavaSchool that won't teach C and won't teach
Scheme is not really teaching computer science, either.  --  Joel Spolsky
From: Alexander Burger
Subject: Re: No Need for Macros (Was: What is the main advantage of macros over functions?)
Date: 
Message-ID: <dpvql3$2cl$1@online.de>
Rob Warnock <····@rpw3.org> wrote:
> Majorinc, Kazimir  <·····@email.address> wrote:
> +---------------
> | I've frequently read that macros are one of the most important 
> | strengths of Lisp, however, I do not understand why. 
> ...
> | Am I missing something here? 
> +---------------

> Yes. Take a look at, say, HTOUT <http://www.cliki.net/htout> or
> CL-WHO <http://www.cliki.net/CL-WHO>, both of which let you write
> things like this:

>     (let ((title "Simple Test Page"))
>       (with-html-output (s *standard-output*)
>         (:html
>           (:head (:title title)) (lfd)
>           ((:body :bgcolor "#d0d0ff")
>            (:h1 title) (lfd)
>            "This is a small demo table:" (lfd)
>            (:table (lfd)
>              (:tr (:th "i") (:th "2^i") (:th "10^i")) (lfd)
>              (loop for i below 5
>                    for 2^i = (expt 2 i)
>                    and 10^i = (expt 10 i) do
>                (htm (:tr (:td i) (:tr 2^i) (:tr 10^i))
>                     (lfd))))))))

> and get this output:

>     <HTML><HEAD><TITLE>Simple Test Page</TITLE></HEAD>
>     <BODY BGCOLOR='#d0d0ff'><H1>Simple Test Page</H1>
>     This is a small demo table:
>     <TABLE>
>     <TR><TH>i</TH><TH>2^i</TH><TH>10^i</TH></TR>
>     <TR><TD>0</TD><TR>1</TR><TR>1</TR></TR>
>     <TR><TD>1</TD><TR>2</TR><TR>10</TR></TR>
>     <TR><TD>2</TD><TR>4</TR><TR>100</TR></TR>
>     <TR><TD>3</TD><TR>8</TR><TR>1000</TR></TR>
>     <TR><TD>4</TD><TR>16</TR><TR>10000</TR></TR>
>     </TABLE></BODY></HTML>

Hm, btw, there's something wrong with the <TR>'s


> Yes, you can do HTML generation without macros, but it
> tends to be ugly and full of deeply-nested LAMBDAs...

Perhaps in Common Lisp ... but it's different in Pico Lisp, where the
use of functions is more general and flexible.

In the following example, 'html', '<h1>', '<table>' and '<row>' are
plain functions just as 'print', 'for' and 'let'. This works well
because in Pico Lisp the internal representations for code and data are
identical (the code is not transformed by compilation), and so these
functions can trivially handle their code body arguments. There's almost
never a need for macros.

(load "lib/http.l" "lib/xhtml.l")

(let Title "Simple Test Page"
   (html NIL Title NIL NIL
      (<h1> NIL Title)
      (<table> NIL "This is a small demo table:"
         '((NIL "i") (NIL "2\^i") (NIL "10\^i"))
         (for (I 0 (> 5 I) (inc I))
            (<row> NIL (print I) (print (** 2 I)) (print (** 10 I))) ) ) ) )

Also note that this is very fast (around 0.1 msec), because it can be
executed on the fly when the file is loaded.

It produces the output:

HTTP/1.1 200 OK
Server: PicoLisp
Connection: close
Content-Type: text/html; charset=utf-8

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
               "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Simple Test Page</title>
</head>
<body><h1>Simple Test Page</h1>
<table><caption>This is a small demo table:</caption>
<tr><th>i</th>
<th>2^i</th>
<th>10^i</th>
</tr>
<tr><td>0</td>
<td>1</td>
<td>1</td>
</tr>
<tr><td>1</td>
<td>2</td>
<td>10</td>
</tr>
<tr><td>2</td>
<td>4</td>
<td>100</td>
</tr>
<tr><td>3</td>
<td>8</td>
<td>1000</td>
</tr>
<tr><td>4</td>
<td>16</td>
<td>10000</td>
</tr>
</table>
</body>
</html>

Cheers,
- Alex
-- 
   Alexander Burger
   Software Lab. / 7fach GmbH
   Bahnhofstr. 24a, D-86462 Langweid
   ···@software-lab.de, http://www.software-lab.de, +49 821 9907090
From: Rob Warnock
Subject: Re: No Need for Macros (Was: What is the main advantage of macros over functions?)
Date: 
Message-ID: <C9OdnfR5A6_OB17enZ2dnUVZ_v-dnZ2d@speakeasy.net>
Alexander Burger  <···@software-lab.de> wrote:
+---------------
| Rob Warnock <····@rpw3.org> wrote:
| >              (loop for i below 5
| >                    for 2^i = (expt 2 i)
| >                    and 10^i = (expt 10 i) do
| >                (htm (:tr (:td i) (:tr 2^i) (:tr 10^i))
| >                     (lfd))))))))
...
| >     <TR><TD>0</TD><TR>1</TR><TR>1</TR></TR>
| >     <TR><TD>1</TD><TR>2</TR><TR>10</TR></TR>
| >     <TR><TD>2</TD><TR>4</TR><TR>100</TR></TR>
| >     <TR><TD>3</TD><TR>8</TR><TR>1000</TR></TR>
| >     <TR><TD>4</TD><TR>16</TR><TR>10000</TR></TR>
| >     </TABLE></BODY></HTML>
| 
| Hm, btw, there's something wrong with the <TR>'s
+---------------

Oops! Yup, I typo'd the sexpr:

    (htm (:tr (:td i) (:tr 2^i) (:tr 10^i)) (lfd))
		        **        **
which should have been:

    (htm (:tr (:td i) (:td 2^i) (:td 10^i)) (lfd))
		        **        **
Thanks for the catch!


-Rob

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: tichy
Subject: Re: No Need for Macros (Was: What is the main advantage of macros over functions?)
Date: 
Message-ID: <dq59s5$5ep$1@atlantis.news.tpi.pl>
Alexander Burger wrote:
...
> Perhaps in Common Lisp ... but it's different in Pico Lisp, where the
> use of functions is more general and flexible. 
...

I just started writing similar thing (html generation using functions)
in CL.

Regards, Szymon.
From: Kenny Tilton
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <KM2vf.26237$GW1.14232@news-wrt-01.rdc-nyc.rr.com>
Majorinc wrote:
> I've frequently read that macros are one of the most important 
> strengths of Lisp, however, I do not understand why. 
> 
> Only advantage of Lisp macros over Lisp functions I see are 
> slight increase of the speed and few quotes and perhaps 
> arguments less. Not really much ...
> 
> Am I missing something here? 
> 

No. You have no need for macros. The other respondents sound 
unconvincing for a reason: not one of them had a need for macros when 
they started programming Lisp.

I speak without fear of contradiction, because everything I write now is 
a macro, yet when I first started programming (a) I read On Lisp; (b) 
got excited; (c) had a ball with Lisp; and (d) could not for the life of 
me think of an excuse for writing a macro.

Learning Lisp is like getting repotted. You grow into needing macros.

kenny
From: Edi Weitz
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <uwthfhxja.fsf@agharta.de>
On Thu, 05 Jan 2006 06:11:54 GMT, Kenny Tilton <·············@nyc.rr.com> wrote:

> Learning Lisp is like getting repotted.

Hey, that's one for the .sig file... :)

-- 

Lisp is not dead, it just smells funny.

Real email: (replace (subseq ·········@agharta.de" 5) "edi")
From: Philippe Lorin
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <43bcf8e0$0$21554$636a15ce@news.free.fr>
Kenny Tilton wrote:
> No. You have no need for macros. The other respondents sound 
> unconvincing for a reason: not one of them had a need for macros when 
> they started programming Lisp.

I'm not sure you're being serious. I'm not one of the other respondents, 
but I guess you're making a generalization. Macros were one major reason 
I switched to Lisp. I was tired of implementing specific macro systems / 
DSLs as pre-compilers or crappy #define's. Thus, when I started 
programming Lisp, the first thing I wanted was take advantage of macros.


> I speak without fear of contradiction, because everything I write now is 
> a macro, yet when I first started programming (a) I read On Lisp; (b) 
> got excited; (c) had a ball with Lisp; and (d) could not for the life of 
> me think of an excuse for writing a macro.

I admit I didn't feel the need for macros before years of programming. 
But the OP doesn't say he's new to programming.
From: Michael
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <slrndrrjm2.5iu.malus42@yahoo.com>
On 2006-01-05, Kenny Tilton <·············@nyc.rr.com> wrote:
>  No. You have no need for macros. The other respondents sound 
>  unconvincing for a reason: not one of them had a need for macros when 
>  they started programming Lisp.
> 
>  I speak without fear of contradiction, because everything I write now is 
>  a macro, yet when I first started programming (a) I read On Lisp; (b) 
>  got excited; (c) had a ball with Lisp; and (d) could not for the life of 
>  me think of an excuse for writing a macro.

Well technically we could just write everything in assembly language so
why bother with a high level language at all? I mean after all, if you
have goto and labels then why bother with functions :)

Maybe because it makes life easier. So while you don't _need_ macros any
more than you _need_ a sports car, both are nice when you have them.
From: Denis Bueno
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <dbuenoAOEU-76AB7B.12144805012006@localhost>
In article <··························@news.carnet.hr>,
 Majorinc, Kazimir <·····@email.address> wrote:
> Only advantage of Lisp macros over Lisp functions I see are 
> slight increase of the speed and few quotes and perhaps 
> arguments less. Not really much ...
> 
> Am I missing something here? 

Consider the IF form. What is the semantics of the following? (Ignore, for
the moment, the fact that writing a piece of code like this is idiotic.)

  (if (always-return-true)
      (run-a-safe-function)
      (vogons-nuke-the-world-for-hyperspace-bypass))

When this form is executed, (always-return-true) is executed on its own,
returning true. This causes the IF form to evaluate to the result of
(run-a-safe-function), which, presumably, does just that. According to the
semantics of IF, there is *no way* for the (...nuke-the-world...) function
to be executed, since the test always returns true. There are a significant
number of people who will agree that this is probably a good thing.

Now, let's write MY-IF, a function whose semantics we would like to be the
same as IFs. We'll write it in terms of COND.

  (defun my-if (condition then-result else-result)
    (cond (condition then-result)
          (t else-result)))

Suppose you evaluate the above IF form, but with IF changed to
MY-IF. What's going to happen? According to the rules of function
application[0], *all the arguments to MY-IF get evaluated, left-to-right,
and /then/ the body of the function is run*. Whoops. The Vogons get their
way.

How do you get out of the semantic bind? Macros -- macros can control the
order of evaluation of their arguments, thus obviating the issue. Macros
allow you to write your own control constructs, extending the
language's. And they can be arbitrarily complicated.

Convinced?

[0]
http://www.ai.mit.edu/projects/iiip/doc/CommonLISP/HyperSpec/Body/sec_3-1-2-1-2-3
.html
From: Majorinc, Kazimir
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <MPG.1e27863e20f80911989683@news.carnet.hr>
In article <································@localhost>, 
··········@UEOAstygian.net says...


> In article <··························@news.carnet.hr>,
>  Majorinc, Kazimir <·····@email.address> wrote:
> > Only advantage of Lisp macros over Lisp functions I see are 
> > slight increase of the speed and few quotes and perhaps 
> > arguments less. Not really much ...
> > 
> > Am I missing something here? 
> 
> Consider the IF form. What is the semantics of the following? (Ignore, for
> the moment, the fact that writing a piece of code like this is idiotic.)
> 
>   (if (always-return-true)
>       (run-a-safe-function)
>       (vogons-nuke-the-world-for-hyperspace-bypass))
> 
> When this form is executed, (always-return-true) is executed on its own,
> returning true. This causes the IF form to evaluate to the result of
> (run-a-safe-function), which, presumably, does just that. According to the
> semantics of IF, there is *no way* for the (...nuke-the-world...) function
> to be executed, since the test always returns true. There are a significant
> number of people who will agree that this is probably a good thing.
> 
> Now, let's write MY-IF, a function whose semantics we would like to be the
> same as IFs. We'll write it in terms of COND.
> 
>   (defun my-if (condition then-result else-result)
>     (cond (condition then-result)
>           (t else-result)))
> 
> Suppose you evaluate the above IF form, but with IF changed to
> MY-IF. What's going to happen? According to the rules of function
> application[0], *all the arguments to MY-IF get evaluated, left-to-right,
> and /then/ the body of the function is run*. Whoops. The Vogons get their
> way.
> 
> How do you get out of the semantic bind? Macros -- macros can control the
> order of evaluation of their arguments, thus obviating the issue. Macros
> allow you to write your own control constructs, extending the
> language's. And they can be arbitrarily complicated.
> 
> Convinced?

I could use your my-if and call it this way

(eval (my-if (always return true) 
            '(run-a safe-function)
            '(vogons-nuke-the-world-for-hyperspace-bypass)
      )
)


That requires one eval and two quotes more, however, it does 
not look as big disadvantage of functions over macros - 
especially if there is some abbreviation for eval like it is 
for quote. (^ and ? could be great pair for eval and quote.)

On the other side, using functions instead of macros have some 
other benefits. Rainer listed few in his post, I can think of 
another one: uniform syntax. Without macros programmer (or 
program) does not need to test type of operator to know if 
arguments are evaluated before operator call. 

So, I still do not understand the advantage of macros. Are they 
here only to spare us these very few quotes and evals? 
 
From: Denis Bueno
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <dbuenoAOEU-74B72E.16350505012006@localhost>
In article <··························@news.carnet.hr>,
 Majorinc, Kazimir <·······@chem.pmf.hr> wrote:
> I could use your my-if and call it this way
> 
> (eval (my-if (always return true) 
>             '(run-a safe-function)
>             '(vogons-nuke-the-world-for-hyperspace-bypass)
>       )
> )

Three things.

1) Fix your parentheses. A lisper with any taste (redundant?) will likely
   recoil in horror on seeing code like that. It should look like this:

    (eval (my-if (always-return-true)
                 '(run-a-safe-function)
                 '(vogons-nuke-the-world-for-hyperspace-bypass)))

2) If that code is supposed to be typed into the REPL, Calling EVAL there
   is unnecessary. This will have the same effect:
         (my-if (always-return-true)
                '(run-a-safe-function)
                '(vogons-nuke-the-world-for-hyperspace-bypass))

3) As a consequence of (2), it is not EVAL but QUOTE (or ') which is giving
   you the effect of not evaluating the arguments to MY-IF.

   Using QUOTE explicitly to prevent evaluation does not preserve the
   semantics of IF. As I noted in my previous post, IF results in the
   result of evaluating its 'then' form (if the condition is true), not the
   'then' form itself (unevaluated). Thus calling MY-IF with quoted
   arguments does not work at all, in the sense that it has different
   semantics from IF.

   If you want to write a function that works kinda-like IF does, there are
   as many good possibilities as ideas. =]

   If you were to run MY-IF in the way you suggested, the result would be:
   (RUN-A-SAFE-FUNCTION). That is, it would be a list containing one
   element, a symbol. And *not* the result of a function call.


* (if t (print 3) (print 4))
3 
3 ; returns what (print 3) returns, and doesn't evaluate (print 4)

* (defmacro my-if (condition then-result else-result)
          `(cond (,condition ,then-result)
                 (t ,else-result)))

MY-IF
* (my-if t (print 3) (print 4))
3 
3 ; returns what (print 3) returns, and doesn't evaluate (print 4)

* (defun fn-if (condition then-result else-result)
    (cond (condition then-result)
          (t else-result)))

FN-IF

* (fn-if t (print 3) (print 4))

3 ; evaluate then-condition BEFORE calling FN-IF
4 ; evaluate else-condition BEFORE calling FN-IF
3 ; return then-condition


The point of all this, then, is that you can add new operators (not just
library functions) into the language which are *fully integrated* into the
syntax. I could alias the built-in IF, and write my own, and call them IF1
and IF2, and present them to you, and you would use the same syntax in your
code for either of them. Judging by syntax alone you couldn't tell the
difference. If IF were defined as a function, as you suggest it can be, you
could tell the difference -- i.e., the syntax has to be different, because
the caller must quote the arguments, and evaluate whatever result the IF
function gives. Once you've added a new operator, you have in effect
extended the Common Lisp language into your own language, which consists of
Common Lisp plus whatever new operator you've defined.

There are many other different, nifty things you can do with macros. But to
me, this is a fundamental ability that macros give you.

-Denis
From: Pascal Costanza
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <425aesF1hetr1U1@individual.net>
Majorinc wrote:

> I could use your my-if and call it this way
> 
> (eval (my-if (always return true) 
>             '(run-a safe-function)
>             '(vogons-nuke-the-world-for-hyperspace-bypass)
>       )
> )
> 
> 
> That requires one eval and two quotes more, however, it does 
> not look as big disadvantage of functions over macros - 
> especially if there is some abbreviation for eval like it is 
> for quote. (^ and ? could be great pair for eval and quote.)

eval invokes the full Lisp interpreter or compiler at runtime. It either 
has to interpret the code that it is passed, no matter whether the 
underlying implementation is compiled or not, or it has to first compile 
the code and then execute it. Since the compilation happens at runtime 
in that case, it is a very expensive operation.

Secondly, eval cannot see lexical bindings, only global ones. The 
following code produces an error:

(let ((x 42))
   (eval 'x))

...unless x is also bound globally. Theoretically, it is possible that 
eval sees local bindings (and there are a few Lisp implementations that 
support this), but again this has serious performance penalties.

So a good rule of thumb is: Never use eval. Use something else instead. 
(Exceptions have been discussed before, in comp.lang.lisp and elsewhere.)

> On the other side, using functions instead of macros have some 
> other benefits. Rainer listed few in his post, I can think of 
> another one: uniform syntax. Without macros programmer (or 
> program) does not need to test type of operator to know if 
> arguments are evaluated before operator call. 
> 
> So, I still do not understand the advantage of macros. Are they 
> here only to spare us these very few quotes and evals? 

Try to learn macroprogramming with a good tutorial. Try to implement 
some interesting macros. Compare them with functional equivalents. 
Hopefully, you will notice that macros can help to simplify what the 
user of your libraries has to write.

There is a possibility that the advantage of having macros in a language 
doesn't convince you. Other languages force you to think in the fixed 
set of syntactic abstractions that are offered by those languages, and 
nothing else. Some people think this is an advantage.

There is no strict necessity to have macros in a programming language. 
There is no strict necessity to have anything in a programming language, 
provided it is Turing complete. (In some domains, not even that is 
important.) The computer doesn't care what constructs we use to tell it 
what to do.

Many (most?) Lispers think that macros offer some substantial benefits. 
I am convinced that the important benefit is that macros can help to 
hide implementation details that you cannot hide otherwise. The purely 
functional versions of 'when in this thread require the user to say 
either 'lambda or (in your example) 'eval explicitly, although it 
strictly shouldn't matter how 'when is implemented. There are larger and 
more convincing examples - for example, you can find some in good Common 
Lisp tutorials. If they don't convince, then maybe Lisp is not the right 
programming language for you.


Pascal

-- 
My website: http://p-cos.net
Closer to MOP & ContextL:
http://common-lisp.net/project/closer/
From: Frank Buss
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <1ql6f1n7sng1a.h9ir1p95jqry$.dlg@40tude.net>
Majorinc, Kazimir wrote:

> Only advantage of Lisp macros over Lisp functions I see are 
> slight increase of the speed and few quotes and perhaps 
> arguments less. Not really much ...
> 
> Am I missing something here?

For me the main advantage with macros is to write less code, because you
don't need to write "lambda" all the time, which helps in reading the code,
too. An important example is the "with"-idiom, e.g. with-open-file from the
hyperspec:

(with-open-file (s "test.txt" :direction :output :if-exists :supersede)
    (format s "Here are a couple~%of test data lines~%"))

This macro is implemented like this (simplified code do to show the
important things)

(defmacro with-open-file ((stream filename &key direction if-exists)
                           &body body)
  `(let ((,stream (open ,filename
                        :direction ,direction
                        :if-exists ,if-exists)))
     (ignore-errors ,@body)
     (close ,stream)))

With this macro you can't forget to close the stream. Of course, you can
write it with a function, too:

(defun with-open-file (filename function &key direction if-exists)
  (let ((stream (open filename
                      :direction direction
                      :if-exists if-exists)))
    (ignore-errors (funcall function stream))
    (close stream)))

but then you have to use lambda, which is a bit longer and more difficult
to read (at least for me)

(with-open-file
 "test.txt"
 (lambda (s)
   (format s "Here are a couple~%of test data lines~%"))
 :direction :output :if-exists :supersede)

It's even more interesting with nested macros. The macro version:

(with-my-sound-output sound-stream
  (with-open-file (file-stream "test.wav" :direction :input)
    (copy-stream :from file-stream :to sound-stream)))

and the version with functions:

(with-my-sound-output
 (lambda (sound-stream)
   (with-open-file
    "test.wav"
    (lambda (file-stream)
      (copy-stream :from file-stream :to sound-stream))
    :direction :input)))

But this is something you could almost do with "#define" in C, too.
Something you can't do with #defines e.g. the infix package:

http://www.cs.cmu.edu/afs/cs/project/ai-repository/ai/lang/lisp/code/syntax/infix/0.html

Then you can write something like this:

(let ((a 1) (b 2)) #I"a+b") -> 3

The important thing is, that the expansion is done at compile time:

(macroexpand '#I"a+b") -> (+ A B)

This won't work with functions and eval, because eval can't access the
lexical environment and of course, eval would be much slower.

See all the pre-compilers and code-generators in other languages, like the
new annotations in Java, AspectJ, GUI code generator wizards, EJB, CORBA,
COM etc. for reasons why you want to have macros and only one Lisp source
file and one Lisp environment.

-- 
Frank Buss, ··@frank-buss.de
http://www.frank-buss.de, http://www.it4-systems.de
From: Rainer Joswig
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <joswig-D1DD0B.00382906012006@news-europe.giganews.com>
In article <·······························@40tude.net>,
 Frank Buss <··@frank-buss.de> wrote:


Data and procedures and the values they amass,
Higher-order functions to combine and mix and match,
Objects with their local state, the messages they pass,
A property, a package, the control point for a catch-
In the Lambda Order they are all first-class.
One Thing to name them all, One Thing to define them,
One Thing to place them in environments and bind them,
In the Lambda Order they are all first-class.
                -- The TI PC Scheme Manual


> Majorinc, Kazimir wrote:
> 
> > Only advantage of Lisp macros over Lisp functions I see are 
> > slight increase of the speed and few quotes and perhaps 
> > arguments less. Not really much ...
> > 
> > Am I missing something here?
> 
> For me the main advantage with macros is to write less code, because you
> don't need to write "lambda" all the time, which helps in reading the code,

Actually, if one is allergic to reading Lambda one may better not use
Lisp.

Not liking to type or read LAMBDA is at the same level of not liking
parentheses.



> too. An important example is the "with"-idiom, e.g. with-open-file from the
> hyperspec:
> 
> (with-open-file (s "test.txt" :direction :output :if-exists :supersede)
>     (format s "Here are a couple~%of test data lines~%"))
> 
> This macro is implemented like this (simplified code do to show the
> important things)
> 
> (defmacro with-open-file ((stream filename &key direction if-exists)
>                            &body body)
>   `(let ((,stream (open ,filename
>                         :direction ,direction
>                         :if-exists ,if-exists)))
>      (ignore-errors ,@body)
>      (close ,stream)))
> 
> With this macro you can't forget to close the stream. Of course, you can
> write it with a function, too:
> 
> (defun with-open-file (filename function &key direction if-exists)
>   (let ((stream (open filename
>                       :direction direction
>                       :if-exists if-exists)))
>     (ignore-errors (funcall function stream))
>     (close stream)))
> 
> but then you have to use lambda, which is a bit longer and more difficult
> to read (at least for me)

The bit longer reading pays back big if you use the advantage of
a functional programming style.

Macros can't be passed around. Functions can be.

> (with-open-file
>  "test.txt"
>  (lambda (s)
>    (format s "Here are a couple~%of test data lines~%"))
>  :direction :output :if-exists :supersede)
> 
> It's even more interesting with nested macros. The macro version:
> 
> (with-my-sound-output sound-stream
>   (with-open-file (file-stream "test.wav" :direction :input)
>     (copy-stream :from file-stream :to sound-stream)))
> 
> and the version with functions:
> 
> (with-my-sound-output
>  (lambda (sound-stream)
>    (with-open-file
>     "test.wav"
>     (lambda (file-stream)
>       (copy-stream :from file-stream :to sound-stream))
>     :direction :input)))
> 
> But this is something you could almost do with "#define" in C, too.
> Something you can't do with #defines e.g. the infix package:
> 
> http://www.cs.cmu.edu/afs/cs/project/ai-repository/ai/lang/lisp/code/syntax/infix/0.html
> 
> Then you can write something like this:
> 
> (let ((a 1) (b 2)) #I"a+b") -> 3
> 
> The important thing is, that the expansion is done at compile time:

No, #I is a so-called READMACRO. Expansion is done at read time.

Readmacros are a completely different mechanism. Macros and Readmacros
are different things.

> 
> (macroexpand '#I"a+b") -> (+ A B)

Try:

'#I"a+b"

> 
> This won't work with functions and eval, because eval can't access the
> lexical environment and of course, eval would be much slower.
> 
> See all the pre-compilers and code-generators in other languages, like the
> new annotations in Java, AspectJ, GUI code generator wizards, EJB, CORBA,
> COM etc. for reasons why you want to have macros and only one Lisp source
> file and one Lisp environment.

See also the 'Lambda Nature Fortune Cookies':

http://www.gotlisp.com/lambda/lambda.txt

-- 
http://lispm.dyndns.org/
From: Frank Buss
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <1e7dnnx8u08ko.11fu2qz89g3g2$.dlg@40tude.net>
Rainer Joswig wrote:

> Actually, if one is allergic to reading Lambda one may better not use
> Lisp.
> 
> Not liking to type or read LAMBDA is at the same level of not liking
> parentheses.

I don't care about parentheses, because you don't need to read them very
often, if the code is properly indented. But with LAMBDA you have to read
and think about it, when it is used. Perhaps it should be written λ, then
it would be easier to read.

> The bit longer reading pays back big if you use the advantage of
> a functional programming style.
> Macros can't be passed around. Functions can be.

Yes, this is useful sometimes, but for me the with-* idiom is one of the
cases where a macro is simpler, something the Common Lisp designers have
thought, too. I can't imaging a real world example, where you want to pass
with-open-file like a function to another function.

> Readmacros are a completely different mechanism. Macros and Readmacros
> are different things.

They are both macros, otherwise the name "reader macro" wouldn't make
sense. Both generates code, the difference is that macros defined with
defmacro are expanded at compile time and reader macros at read time and
how you pass parameters to the macro generating function.

But I agree that you should use macros only for really useful cases, like
for the infix reader macro or implementing patterns like the with-* pattern
(a similar pattern is know as RAII in C++), which normally are not passed
as function arguments.

BTW: I'm not allergic to λ, but perhaps I like macros more than you :-)
http://www.frank-buss.de/lisp/functional.html

> See also the 'Lambda Nature Fortune Cookies':
> 
> http://www.gotlisp.com/lambda/lambda.txt

Nice. I like this one:

===  ALL USERS PLEASE NOTE  ========================

There has been some confusion concerning MAPCAR.
        (DEFUN MAPCAR (&FUNCTIONAL FCN &EVAL &REST LISTS)
                (PROG (V P LP)
                (SETQ P (LOCF V))
        L       (SETQ LP LISTS)
                (%START-FUNCTION-CALL FCN T (LENGTH LISTS) NIL)
        L1      (OR LP (GO L2))
                (AND (NULL (CAR LP)) (RETURN V))
                (%PUSH (CAAR LP))
                (RPLACA LP (CDAR LP))
                (SETQ LP (CDR LP))
                (GO L1)
        L2      (%FINISH-FUNCTION-CALL FCN T (LENGTH LISTS) NIL)
                (SETQ LP (%POP))
                (RPLACD P (SETQ P (NCONS LP)))
                (GO L)))
We hope this clears up the many questions we've had about it.

-- 
Frank Buß, ··@frank-buss.de
http://www.frank-buss.de, http://www.it4-systems.de
From: Rainer Joswig
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <joswig-8656A6.08203106012006@news-europe.giganews.com>
In article <································@40tude.net>,
 Frank Buss <··@frank-buss.de> wrote:

> Rainer Joswig wrote:
> 
> > Actually, if one is allergic to reading Lambda one may better not use
> > Lisp.
> > 
> > Not liking to type or read LAMBDA is at the same level of not liking
> > parentheses.
> 
> I don't care about parentheses, because you don't need to read them very
> often, if the code is properly indented. But with LAMBDA you have to read
> and think about it, when it is used. Perhaps it should be written λ, then
> it would be easier to read.

Of course you have to think about it. If LAMBDA does not make
you think, then it would not be useful. Avoiding LAMBDA because
of 'low readability' is just another 'beginner' error.

Using the greek lambda character, which I have seen used by some
Lisp authors, doesn't help you much, I'd say.

> 
> > The bit longer reading pays back big if you use the advantage of
> > a functional programming style.
> > Macros can't be passed around. Functions can be.
> 
> Yes, this is useful sometimes, but for me the with-* idiom is one of the
> cases where a macro is simpler, something the Common Lisp designers have
> thought, too. I can't imaging a real world example, where you want to pass
> with-open-file like a function to another function.

No?

(defun curry (function arg)
  (lambda (&rest args)
    (apply function arg args)))

(defun call-with-stream (function file)
  (with-open-file (stream file)
    (funcall function stream)))

(defun count-lines-in-stream (stream)
  (loop for line = (read-line stream nil nil)
        while line count line))

Now you want to count lines of some files.


CL-USER 5 > (reduce #'+
                    (mapcar
                     (curry #'call-with-stream #'count-lines-in-stream) 
                     (directory "http:lw;**;.lisp")))
5559

Not many LAMBDAs here, but combining functions.

It is called Functional Programming and pretty powerful.

> 
> > Readmacros are a completely different mechanism. Macros and Readmacros
> > are different things.
> 
> They are both macros, otherwise the name "reader macro" wouldn't make
> sense.

With this reasoning ships and spaceships are both ships. Well, yes.
And both have a captain.

> Both generates code,

The purpose of READMACROs is not to generate code.
The purpose is to transform characters from input streams to Lisp
data. It is perfectly legal and useful to generate data
with READMACROs.

Say you have a file that contains lines with some encoding of data.
It is perfectly fine to use a readmacro in the text and to read the data
using READ.  See also the XAPPING example in CLtL2.

Readmacros may also be used for just consuming some characters
from a stream. For example If you have a readmacro for comments,
the comment might just be ignored, but read from the stream.

> the difference is that macros defined with
> defmacro are expanded at compile time and reader macros at read time and
> how you pass parameters to the macro generating function.

There are all kinds of differences.

Readmacros
- input is a stream
- output is Lisp data or even no data
- Readmacros are used to extend the READer
- the API is completely different from Macros

Macros
- input is a Lisp form
- output is some Lisp data
- Macros are used from the macro expander
  (which is used by EVAL, COMPILE, COMPILE-FILE, ...)

Again, readmacros and macros are very different mechanisms.
Readmacros are not a sub-concept of macros.

> But I agree that you should use macros only for really useful cases, like
> for the infix reader macro or implementing patterns like the with-* pattern
> (a similar pattern is know as RAII in C++), which normally are not passed
> as function arguments.
> 
> BTW: I'm not allergic to λ, but perhaps I like macros more than you :-)
> http://www.frank-buss.de/lisp/functional.html

Yes, that's Functional Geometry. Lisp already supports
Functional Programming. Functional Geometry is
an application of Functional Programming.
If you find Functional Geometry useful, you may find
Functional Programming in general useful.
Just as you combine functions to generate more
complex pictures, you combine functions in Lisp
for 'ordinary' programming. Say, you can write
Functional File Handling.

> 
> > See also the 'Lambda Nature Fortune Cookies':
> > 
> > http://www.gotlisp.com/lambda/lambda.txt
> 
> Nice. I like this one:
> 
> ===  ALL USERS PLEASE NOTE  ========================
> 
> There has been some confusion concerning MAPCAR.
>         (DEFUN MAPCAR (&FUNCTIONAL FCN &EVAL &REST LISTS)
>                 (PROG (V P LP)
>                 (SETQ P (LOCF V))
>         L       (SETQ LP LISTS)
>                 (%START-FUNCTION-CALL FCN T (LENGTH LISTS) NIL)
>         L1      (OR LP (GO L2))
>                 (AND (NULL (CAR LP)) (RETURN V))
>                 (%PUSH (CAAR LP))
>                 (RPLACA LP (CDAR LP))
>                 (SETQ LP (CDR LP))
>                 (GO L1)
>         L2      (%FINISH-FUNCTION-CALL FCN T (LENGTH LISTS) NIL)
>                 (SETQ LP (%POP))
>                 (RPLACD P (SETQ P (NCONS LP)))
>                 (GO L)))
> We hope this clears up the many questions we've had about it.

-- 
http://lispm.dyndns.org/
From: Frank Buss
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <jl717un278zv.13dotre9d5dta.dlg@40tude.net>
Rainer Joswig wrote:

> (defun curry (function arg)
>   (lambda (&rest args)
>     (apply function arg args)))
> 
> (defun call-with-stream (function file)
>   (with-open-file (stream file)
>     (funcall function stream)))
> 
> (defun count-lines-in-stream (stream)
>   (loop for line = (read-line stream nil nil)
>         while line count line))
> 
> Now you want to count lines of some files.
> 
> 
> CL-USER 5 > (reduce #'+
>                     (mapcar
>                      (curry #'call-with-stream #'count-lines-in-stream) 
>                      (directory "http:lw;**;.lisp")))
> 5559
> 
> Not many LAMBDAs here, but combining functions.
> 
> It is called Functional Programming and pretty powerful.

I don't think this is a good real world example, because most Lisp
programmers would write your 13 lines with these 4 lines:

(loop for path in (directory "http:lw;**;.lisp") sum
      (with-open-file (stream path)
        (loop for line = (read-line stream nil nil)
              while line count line)))

But in general you are right, functional programming is very powerful,
maybe I'm just too accustomed to imperative programming.

-- 
Frank Buss, ··@frank-buss.de
http://www.frank-buss.de, http://www.it4-systems.de
From: André Thieme
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <1136561457.300702.67710@g47g2000cwa.googlegroups.com>
Frank Buss schrieb:

> Rainer Joswig wrote:
>
> > (defun curry (function arg)
> >   (lambda (&rest args)
> >     (apply function arg args)))
> >
> > (defun call-with-stream (function file)
> >   (with-open-file (stream file)
> >     (funcall function stream)))
> >
> > (defun count-lines-in-stream (stream)
> >   (loop for line = (read-line stream nil nil)
> >         while line count line))

Paul Graham calls functions like these "Utility Functions".
Lets assume we have them already defined in our app cause we use them
several times.
We can then simply write these three lines:

(reduce #'+ (mapcar
             (curry #'call-with-stream #'count-lines-in-stream)
             (directory "http:lw;**;.lisp")))

Instead of these four:

> (loop for path in (directory "http:lw;**;.lisp") sum
>       (with-open-file (stream path)
>         (loop for line = (read-line stream nil nil)
>               while line count line)))


André
--
From: Pascal Costanza
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <427i8fF1h5nn0U1@individual.net>
Andr� Thieme wrote:
> Frank Buss schrieb:
> 
> 
>>Rainer Joswig wrote:
>>
>>
>>>(defun curry (function arg)
>>>  (lambda (&rest args)
>>>    (apply function arg args)))
>>>
>>>(defun call-with-stream (function file)
>>>  (with-open-file (stream file)
>>>    (funcall function stream)))
>>>
>>>(defun count-lines-in-stream (stream)
>>>  (loop for line = (read-line stream nil nil)
>>>        while line count line))
> 
> 
> Paul Graham calls functions like these "Utility Functions".
> Lets assume we have them already defined in our app cause we use them
> several times.
> We can then simply write these three lines:
> 
> (reduce #'+ (mapcar
>              (curry #'call-with-stream #'count-lines-in-stream)
>              (directory "http:lw;**;.lisp")))
> 
> Instead of these four:
> 
> 
>>(loop for path in (directory "http:lw;**;.lisp") sum
>>      (with-open-file (stream path)
>>        (loop for line = (read-line stream nil nil)
>>              while line count line)))

(loop for path in (directory "http:lw;**;.lisp") sum
       (with-open-file (stream path)
         (loop while (read-line stream nil nil) count t)))

;)

Pascal

-- 
My website: http://p-cos.net
Closer to MOP & ContextL:
http://common-lisp.net/project/closer/
From: Rainer Joswig
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <joswig-6D3416.12102406012006@news-europe.giganews.com>
In article <······························@40tude.net>,
 Frank Buss <··@frank-buss.de> wrote:

> Rainer Joswig wrote:
> 
> > (defun curry (function arg)
> >   (lambda (&rest args)
> >     (apply function arg args)))
> > 
> > (defun call-with-stream (function file)
> >   (with-open-file (stream file)
> >     (funcall function stream)))
> > 
> > (defun count-lines-in-stream (stream)
> >   (loop for line = (read-line stream nil nil)
> >         while line count line))
> > 
> > Now you want to count lines of some files.
> > 
> > 
> > CL-USER 5 > (reduce #'+
> >                     (mapcar
> >                      (curry #'call-with-stream #'count-lines-in-stream) 
> >                      (directory "http:lw;**;.lisp")))
> > 5559
> > 
> > Not many LAMBDAs here, but combining functions.
> > 
> > It is called Functional Programming and pretty powerful.
> 
> I don't think this is a good real world example, because most Lisp
> programmers would write your 13 lines with these 4 lines:

I somehow expected that you don't get the point, though
you had the Functional Geometry page mentioned. ;-)

The point is not how much code I wrote for that,
the point is that programming with functions allows
you to write reusable building blocks that can
be combined by the mechanisms of Functional Programming
(Higher Order functions and so on). This leads to
an elegant programming style (less imperative,
more declarative, less side-effects, ...).
So the above functions are simple building blocks that
can be reused and combined over and over.
Functional abstraction is the key to this.
Functions like these are nicely put in some reusable
library.

> 
> (loop for path in (directory "http:lw;**;.lisp") sum
>       (with-open-file (stream path)
>         (loop for line = (read-line stream nil nil)
>               while line count line)))
> 
> But in general you are right, functional programming is very powerful,
> maybe I'm just too accustomed to imperative programming.

Just read these slides from 1993:

http://www.norvig.com/luv-slides.ps

Peter Norvig and Kent Pitman:

  Tutorial on Good Lisp Programming Style

These slides are well done and should be read by every aspiring
Lisp programmer.

They may be old, but a lot of that is still valid.

There are lots of Scheme books which teach similar things
(SICP, HTDP, ...).

For a good introduction into this programming style from
a Common Lisp point of view, I would
recommend to study Paradigms of Artificial Intelligence
Programming by Peter Norvig. It covers a lot of ground
and uses a programming style that uses elements
from Functional Programming - but not much object-oriented
programming.

-- 
http://lispm.dyndns.org/
From: John Thingstad
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <op.s2yh1qm5pqzri1@mjolner.upc.no>
On Fri, 06 Jan 2006 11:15:47 +0100, Frank Buss <··@frank-buss.de> wrote:

>
> But in general you are right, functional programming is very powerful,
> maybe I'm just too accustomed to imperative programming.
>

Well I think you have a point.
Though functional programming is powerfull it quickly becomes
cumbersome. Thake a look at his website and look at the
cl-http code to generate a page. (http://lispm.dyndns.org/)
Now take a look at the reddit video.  
(http://homepage.mac.com/svc/LispMovies/)
I know which I like best.

-- 
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
From: Rainer Joswig
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <BFE42589.24B15%joswig@lisp.de>
Am 06.01.2006 13:23 Uhr schrieb "John Thingstad" unter
<··············@chello.no> in ·················@mjolner.upc.no:

> On Fri, 06 Jan 2006 11:15:47 +0100, Frank Buss <··@frank-buss.de> wrote:
> 
>> 
>> But in general you are right, functional programming is very powerful,
>> maybe I'm just too accustomed to imperative programming.
>> 
> 
> Well I think you have a point.
> Though functional programming is powerfull it quickly becomes
> cumbersome. Thake a look at his website and look at the
> cl-http code to generate a page. (http://lispm.dyndns.org/)

Well you should say at which code you were looking at, since
the code is not published. Only small amounts are visible.
If you saw the snippet that renders a news item, it is
using macros. Tons of macros. That's exactly what makes the
code ugly. Though I can live with it.

The basic CL-HTTP functionality provides a way to generate
pages with macrology. Those are optimized for efficiency
(no consing and so on). It is really a low-level facility.

The next functions are looking differently:

(defun generate-news-item-page (news url stream)
  (destructuring-bind ( &key title &allow-other-keys) news
    (generate-basic-page
     url stream
     :title title
     :show-home-page-link t
     :render-function
     (lambda (url stream)
       (declare (ignore url))
       (princ " &gt; " stream)
       (html:note-anchor "Lisp News" :reference #u"/news.html"
                                     :stream stream)
       (render-news-item-1 news stream)))))


(defun respond-to-news-item-search (url stream)
  (let* ((keys (url:search-keys url))
         (db (symbol-value (url:search-database url)))
         (id (second (assoc :id keys))))
    (when id
      (let ((news (find id db
                        :key (lambda (item)
                               (getf item :id))
                        :test (lambda (a b)
                                (equalp (string a) (string b))))))
        (when news
          (generate-news-item-page news url stream))))))

(http:export-url (lispm-url "/news?")
                 :search
                 :search-database '*lisp-news*
                 :response-function 'respond-to-news-item-search)









Though editing the macro-based Lisp code is not really difficult
- when I'm using a Lisp editor.

> Now take a look at the reddit video.
> (http://homepage.mac.com/svc/LispMovies/)
> I know which I like best.
From: John Thingstad
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <op.s2yr2sx0pqzri1@mjolner.upc.no>
On Fri, 06 Jan 2006 13:47:53 +0100, Rainer Joswig <······@lisp.de> wrote:

Well you have a point. It isn't much to juge from.
I already have redit and I just downloaded cl-http so I can
run a comparison.
Still i think i will find redit's approach is more to my taste.
I use mixed paradigms sometimes functional sometimes macroes.
It depends on the problem. For generating a html page the
chance of reuse is low seems to me while repititious code is high.
I would want to minimze the effort in writing that page.
By my standards macroes win that one.
For my FOL language Formula I used a functional approach.
So I guess I am like Frank in this respect.

> Am 06.01.2006 13:23 Uhr schrieb "John Thingstad" unter
> <··············@chello.no> in ·················@mjolner.upc.no:
>
>> On Fri, 06 Jan 2006 11:15:47 +0100, Frank Buss <··@frank-buss.de> wrote:
>>
>>>
>>> But in general you are right, functional programming is very powerful,
>>> maybe I'm just too accustomed to imperative programming.
>>>
>>
>> Well I think you have a point.
>> Though functional programming is powerfull it quickly becomes
>> cumbersome. Thake a look at his website and look at the
>> cl-http code to generate a page. (http://lispm.dyndns.org/)
>
> Well you should say at which code you were looking at, since
> the code is not published. Only small amounts are visible.
> If you saw the snippet that renders a news item, it is
> using macros. Tons of macros. That's exactly what makes the
> code ugly. Though I can live with it.
>
> The basic CL-HTTP functionality provides a way to generate
> pages with macrology. Those are optimized for efficiency
> (no consing and so on). It is really a low-level facility.
>
> The next functions are looking differently:
>
> (defun generate-news-item-page (news url stream)
>   (destructuring-bind ( &key title &allow-other-keys) news
>     (generate-basic-page
>      url stream
>      :title title
>      :show-home-page-link t
>      :render-function
>      (lambda (url stream)
>        (declare (ignore url))
>        (princ " &gt; " stream)
>        (html:note-anchor "Lisp News" :reference #u"/news.html"
>                                      :stream stream)
>        (render-news-item-1 news stream)))))
>
>
> (defun respond-to-news-item-search (url stream)
>   (let* ((keys (url:search-keys url))
>          (db (symbol-value (url:search-database url)))
>          (id (second (assoc :id keys))))
>     (when id
>       (let ((news (find id db
>                         :key (lambda (item)
>                                (getf item :id))
>                         :test (lambda (a b)
>                                 (equalp (string a) (string b))))))
>         (when news
>           (generate-news-item-page news url stream))))))
>
> (http:export-url (lispm-url "/news?")
>                  :search
>                  :search-database '*lisp-news*
>                  :response-function 'respond-to-news-item-search)
>
>
>
>
>
>
>
>
>
> Though editing the macro-based Lisp code is not really difficult
> - when I'm using a Lisp editor.
>
>> Now take a look at the reddit video.
>> (http://homepage.mac.com/svc/LispMovies/)
>> I know which I like best.
>
>



-- 
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
From: Thomas F. Burdick
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <xcv4q4hmw4x.fsf@conquest.OCF.Berkeley.EDU>
Frank Buss <··@frank-buss.de> writes:

> Majorinc, Kazimir wrote:
> 
> > Only advantage of Lisp macros over Lisp functions I see are 
> > slight increase of the speed and few quotes and perhaps 
> > arguments less. Not really much ...
> > 
> > Am I missing something here?
> 
> For me the main advantage with macros is to write less code, because you
> don't need to write "lambda" all the time, which helps in reading the code,
> too. An important example is the "with"-idiom, e.g. with-open-file from the
> hyperspec:

Ug, the point of macros is *not* to solve some people's
lambda-allergy.  Yes, macros would allow you to write WHEN if it
didn't exist, and allow you to write WHILE if that's your thing
... but if that was all they were good for, I'd say throw them out.
They'd be a kind of cool idea, but that's an aweful lot of overhead
for something so simple.  (While I don't give any credence to "but I
have to type l-a-m-b-d-a" lambda-allergies, I do think that hiding the
implementation of a construct is potentially useful, so hiding lambdas
with macros can be good in that sense).

Where macros have power is in allowing you to build entire
sub-languages, and allowing the introduction of new, powerful
declarative forms.  This is not as amenable to pithy little examples,
but things like Cell's DEFMODEL, C-INPUT, and C-FORMULA macros are
good examples.  Also, Ltk has a DEFWIDGET macro that is used to define
the Tk classes -- it's a simple declarative language that expands into
all the gory details of implementing the Tcl-Lisp bridge and hiding
this from the Lisp user.

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | Free Mumia Abu-Jamal! |
     ,--'    _,'   | Abolish the racist    |
    /       /      | death penalty!        |
   (   -.  |       `-----------------------'
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Jimka
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <1136549251.086866.297390@g47g2000cwa.googlegroups.com>
hi thomas, i think you gave another very good justification for macros
once before.
programming patterns:  Programming Patterns are so important to lisp
programming
that a pattern declaration facility is built into the language.  This
includes simple patterns
like the WHILE loop, but also much more complex paterns like DEFWIDGET
or DEFMODEL...
From: Thomas F. Burdick
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <xcvoe2nkmh8.fsf@conquest.OCF.Berkeley.EDU>
"Jimka" <·····@rdrop.com> writes:

> hi thomas, i think you gave another very good justification for macros
> once before.
> programming patterns:  Programming Patterns are so important to lisp
> programming
> that a pattern declaration facility is built into the language.  This
> includes simple patterns
> like the WHILE loop, but also much more complex paterns like DEFWIDGET
> or DEFMODEL...

I was thinking of things more like MAP-PLIST/DO-PLIST and IF-LET
rather than WHILE.  DO-PLIST is nice, but MAP-PLIST would certainly
suffice.  However, yeah -- macros like IF-LET let you capture a
pattern that wouldn't be possible without macros.  The functional
equivalent of IF-LET[*] works, but leaks enough implementation details
that it's more of a hinderance than a help in understanding the code.

[*] This is particularly true for the variation of IF-LET that I
    prefer, where you don't get the variable bound (always to NIL) in
    the alternate case:
    
      (declare (inline fn-if-let))
      (defun fn-if-let (predicate consequant &optional alternate)
        (let ((val (funcall predicate)))
          (cond
            (val (funcall consequant val))
            (alternate (funcall alternate))
            (t nil))))
      
      (defmacro if-let ((var pred) consequant &optional alternate)
        `(fn-if-let (lambda () ,pred)
                    (lambda (,var) ,consequant)
                    ,(when alternate `(lambda () ,alternate))))

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | Free Mumia Abu-Jamal! |
     ,--'    _,'   | Abolish the racist    |
    /       /      | death penalty!        |
   (   -.  |       `-----------------------'
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Joerg Hoehle
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <uwtgxjqyi.fsf@users.sourceforge.net>
Frank Buss <··@frank-buss.de> writes:
> (defun with-open-file (filename function &key direction if-exists)

I would not use such examples to advocate macros. These are to close
to counter examples, as Scheme shows.  call-with-open-file (Scheme) is
just as usable as with-open-file (except for another lambda and level
of paranthesis, but we all agree that we don't see these anymore since
we reached enlightment, didn't we?)

> This won't work with functions and eval, because eval can't access the
> lexical environment and of course, eval would be much slower.

Indeed, I suggest Kazimir Majorinc digs out 20-30 year old literature,
when people got convinced that dynamic scoping (still in Emacs) is
much more worrisome than lexical scoping (as in Scheme and CL, Pascal,
Modula, Ada, etc.).  This topic has also been covered in this forum a
couple of times, so I suggest again the OP google's around a bit.


> See all the pre-compilers and code-generators in other languages, like the
> new annotations in Java, AspectJ, GUI code generator wizards, EJB, CORBA,
> COM etc. for reasons why you want to have macros and only one Lisp source
> file and one Lisp environment.

Indeed, that's where macros begin to shine: define your own mini/huge
language: design CLOS, LOOP, Iterate, comprehensions, a FFI, a
database access language, an OLAP retrieval language, SXML, all in
SEXP syntax and use macros to mix that with your regular Lisp code!

The SICP book and many other articles from Sussman shows that one can
go very far with a strict functional style, and still be very
readable.
Macros superfluous?  No.  Scheme people would miss the syntax stuff
equally if it were lost from R5RS.  What do you believe eager
comprehensions and other extensions are built upon?  Similarly, Common
Lispers would need to reinvent macros if they were not there.

Regards,
	Jorg Hohle
Telekom/T-Systems Technology Center
From: Tayssir John Gabbour
Subject: Re: What is the main advantage of macros over functions?
Date: 
Message-ID: <1136535281.868534.64130@g43g2000cwa.googlegroups.com>
Majorinc wrote:
> I've frequently read that macros are one of the most important
> strengths of Lisp, however, I do not understand why.
>
> Only advantage of Lisp macros over Lisp functions I see are
> slight increase of the speed and few quotes and perhaps
> arguments less. Not really much ...
>
> Am I missing something here?

Ernst van Waning had a useful talk about this...
http://wiki.alu.org/lisp-user-meeting-amsterdam-april-2004

Tayssir