all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* Is it possible for a macro to expand to nothing?
@ 2009-11-23 14:56 Alan Mackenzie
  2009-11-23 16:03 ` Drew Adams
                   ` (2 more replies)
  0 siblings, 3 replies; 43+ messages in thread
From: Alan Mackenzie @ 2009-11-23 14:56 UTC (permalink / raw
  To: help-gnu-emacs

That is, not to a call to a null defun, but truly to nothing: i.e., the
ensuing code (as least, when byte compiled) will be identical to what it
would have been, had the macro invocation been omitted.

I want something like this:

(defmacro ifdef (condition &rest forms)
  "If the compile time CONDITION is non-nil, dump the FORMS to the
calling defun.  Otherwise do nothing."
  ......)

-- 
Alan Mackenzie (Nuremberg, Germany).



^ permalink raw reply	[flat|nested] 43+ messages in thread

* RE: Is it possible for a macro to expand to nothing?
  2009-11-23 14:56 Is it possible for a macro to expand to nothing? Alan Mackenzie
@ 2009-11-23 16:03 ` Drew Adams
       [not found] ` <mailman.11344.1258992201.2239.help-gnu-emacs@gnu.org>
  2009-11-23 16:49 ` Jeff Clough
  2 siblings, 0 replies; 43+ messages in thread
From: Drew Adams @ 2009-11-23 16:03 UTC (permalink / raw
  To: 'Alan Mackenzie', help-gnu-emacs

> That is, not to a call to a null defun, but truly to nothing: 
> i.e., the
> ensuing code (as least, when byte compiled) will be identical 
> to what it
> would have been, had the macro invocation been omitted.
> 
> I want something like this:
> 
> (defmacro ifdef (condition &rest forms)
>   "If the compile time CONDITION is non-nil, dump the FORMS to the
> calling defun.  Otherwise do nothing."
>   ......)

Hi Alan,

I'm not sure what you mean. But if you mean something like "insert nothing",
then you can do that by producing nil and then using ,@ inside a backquote. IOW,
instead of inserting nil, you splice it in, which means inserting nothing.

HTH.





^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: Is it possible for a macro to expand to nothing?
       [not found] ` <mailman.11344.1258992201.2239.help-gnu-emacs@gnu.org>
@ 2009-11-23 16:31   ` Alan Mackenzie
  2009-11-23 17:29     ` Drew Adams
                       ` (2 more replies)
  0 siblings, 3 replies; 43+ messages in thread
From: Alan Mackenzie @ 2009-11-23 16:31 UTC (permalink / raw
  To: help-gnu-emacs

Drew Adams <drew.adams@oracle.com> wrote:
>> That is, not to a call to a null defun, but truly to nothing:  i.e.,
>> the ensuing code (as least, when byte compiled) will be identical  to
>> what it would have been, had the macro invocation been omitted.

>> I want something like this:

>> (defmacro ifdef (condition &rest forms)
>>   "If the compile time CONDITION is non-nil, dump the FORMS to the
>> calling defun.  Otherwise do nothing."
>>   ......)

> Hi Alan,

> I'm not sure what you mean.

You might not be the only one.  ;-)

I think I want to be able to do this:

    (defun foo ()
      (setq bar 1)
      (ifdef baz (setq bar 2)))

, and if baz is nil at compile time, this function should be identical to

    (defun foo ()
      (setq bar 1))

.

> But if you mean something like "insert nothing", then you can do that
> by producing nil and then using ,@ inside a backquote. IOW, instead of
> inserting nil, you splice it in, which means inserting nothing.

That means I need to have "`,@" in the invoking defun, doesn't it?  Maybe
that would work, even if it is ugly.

> HTH.

-- 
Alan Mackenzie (Nuremberg, Germany).



^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: Is it possible for a macro to expand to nothing?
  2009-11-23 14:56 Is it possible for a macro to expand to nothing? Alan Mackenzie
  2009-11-23 16:03 ` Drew Adams
       [not found] ` <mailman.11344.1258992201.2239.help-gnu-emacs@gnu.org>
@ 2009-11-23 16:49 ` Jeff Clough
  2 siblings, 0 replies; 43+ messages in thread
From: Jeff Clough @ 2009-11-23 16:49 UTC (permalink / raw
  To: help-gnu-emacs

From: Alan Mackenzie <acm@muc.de>
Date: Mon, 23 Nov 2009 14:56:47 +0000 (UTC)

> That is, not to a call to a null defun, but truly to nothing: i.e., the
> ensuing code (as least, when byte compiled) will be identical to what it
> would have been, had the macro invocation been omitted.
> 
> I want something like this:
> 
> (defmacro ifdef (condition &rest forms)
>   "If the compile time CONDITION is non-nil, dump the FORMS to the
> calling defun.  Otherwise do nothing."
>   ......)

I think the short answer to your question is no, you can't do what you
are asking with a macro like this.  You are looking for what you would
get from a C pre-processor #ifdef and that's not what macros in Lisp
do.  Lisp macros do more and different magic than the C pre-processor.

Jeff





^ permalink raw reply	[flat|nested] 43+ messages in thread

* RE: Is it possible for a macro to expand to nothing?
  2009-11-23 16:31   ` Alan Mackenzie
@ 2009-11-23 17:29     ` Drew Adams
  2009-11-23 18:33     ` Pascal J. Bourguignon
       [not found]     ` <mailman.11352.1258997403.2239.help-gnu-emacs@gnu.org>
  2 siblings, 0 replies; 43+ messages in thread
From: Drew Adams @ 2009-11-23 17:29 UTC (permalink / raw
  To: 'Alan Mackenzie', help-gnu-emacs

> I think I want to be able to do this:
> 
>     (defun foo ()
>       (setq bar 1)
>       (ifdef baz (setq bar 2)))
> 
> , and if baz is nil at compile time, this function should be 
> identical to
> 
>     (defun foo ()
>       (setq bar 1))

(defmacro titi (fn)
  `(defun ,fn ()
     (setq bar 1)
     ,@(ifdef baz '((setq bar 2))))))

Assuming that ifdef returns nil if baz is nil, that should give you (defun foo
() (setq bar 1)). If baz is not nil, it should give you this:

(defun foo ()
 (setq bar 1)
 (setq bar 2))

Or something like that.





^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: Is it possible for a macro to expand to nothing?
  2009-11-23 16:31   ` Alan Mackenzie
  2009-11-23 17:29     ` Drew Adams
@ 2009-11-23 18:33     ` Pascal J. Bourguignon
  2009-11-23 18:51       ` Drew Adams
       [not found]       ` <mailman.11354.1259004470.2239.help-gnu-emacs@gnu.org>
       [not found]     ` <mailman.11352.1258997403.2239.help-gnu-emacs@gnu.org>
  2 siblings, 2 replies; 43+ messages in thread
From: Pascal J. Bourguignon @ 2009-11-23 18:33 UTC (permalink / raw
  To: help-gnu-emacs

Alan Mackenzie <acm@muc.de> writes:

> Drew Adams <drew.adams@oracle.com> wrote:
>>> That is, not to a call to a null defun, but truly to nothing:  i.e.,
>>> the ensuing code (as least, when byte compiled) will be identical  to
>>> what it would have been, had the macro invocation been omitted.
>
>>> I want something like this:
>
>>> (defmacro ifdef (condition &rest forms)
>>>   "If the compile time CONDITION is non-nil, dump the FORMS to the
>>> calling defun.  Otherwise do nothing."
>>>   ......)
>
>> Hi Alan,
>
>> I'm not sure what you mean.
>
> You might not be the only one.  ;-)
>
> I think I want to be able to do this:
>
>     (defun foo ()
>       (setq bar 1)
>       (ifdef baz (setq bar 2)))
>
> , and if baz is nil at compile time, this function should be identical to
>
>     (defun foo ()
>       (setq bar 1))
>
> .
>
>> But if you mean something like "insert nothing", then you can do that
>> by producing nil and then using ,@ inside a backquote. IOW, instead of
>> inserting nil, you splice it in, which means inserting nothing.
>
> That means I need to have "`,@" in the invoking defun, doesn't it?  Maybe
> that would work, even if it is ugly.

That wouldn't work, backquote is a quote.

We cannot produce a macro that returns nothing, because as mentionned,
lisp source is not text, but a data structure, and a macro is a
function that always return one form to be inserted in that data
structure.

However, you can return a form that has no side effect: nil or (progn)
are good candidates.  (I'd tend to favor (progn) as the nil code,
since it can be used easily to add forms to it: 
  (append '(progn) '((print 'hi)) '(42))
produces a valid form, while:
  (append 'nil '((print 'hi)) '(42))
doesn't.)

So:  

 (defmacro ifdef (expr &rest body)
   `(progn ,@(and (eval expr) body)))


  (setf baz nil)
  (dolist (baz '(nil t))
     (print (macroexpand '(ifdef baz (setq bar 2)))))

prints:

  (progn)

  (progn (setq bar 2))


Notice that in the case of your example, when baz is nil, the meaning
is changed, since it would return the result of the form returned by
the ifdef macro, not that of the previous form.  You could write:

  (defun foo ()
     (prog1 (setq bar 1)
        (ifdef baz (setq bar 2))))
or:

  (defun foo ()
     (setq bar 1)
     (ifdef baz (setq bar 2))
     bar)

depending on what you want.

(You could also write a two-branch ifdef instead.




Notice that in the case of Common Lisp, there are read-time tests #+
and #-, and read-time evaluation #. that allow you to implement
something similar to C #ifdef:

'(progn #+baz 1 #-baz 2 #.(+ 1 2)) --> (progn 1 3) or (progn 2 3)

Unfortunately the emacs lisp reader is much more primitive...      


-- 
__Pascal Bourguignon__


^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: Is it possible for a macro to expand to nothing?
       [not found]     ` <mailman.11352.1258997403.2239.help-gnu-emacs@gnu.org>
@ 2009-11-23 18:42       ` Pascal J. Bourguignon
  2009-11-23 20:12         ` Drew Adams
       [not found]         ` <mailman.11356.1259007263.2239.help-gnu-emacs@gnu.org>
  2009-11-23 20:09       ` Alan Mackenzie
  1 sibling, 2 replies; 43+ messages in thread
From: Pascal J. Bourguignon @ 2009-11-23 18:42 UTC (permalink / raw
  To: help-gnu-emacs

"Drew Adams" <drew.adams@oracle.com> writes:

>> I think I want to be able to do this:
>> 
>>     (defun foo ()
>>       (setq bar 1)
>>       (ifdef baz (setq bar 2)))
>> 
>> , and if baz is nil at compile time, this function should be 
>> identical to
>> 
>>     (defun foo ()
>>       (setq bar 1))
>
> (defmacro titi (fn)
>   `(defun ,fn ()
>      (setq bar 1)
>      ,@(ifdef baz '((setq bar 2))))))
>
> Assuming that ifdef returns nil if baz is nil, that should give you (defun foo
> () (setq bar 1)). If baz is not nil, it should give you this:
>
> (defun foo ()
>  (setq bar 1)
>  (setq bar 2))
>
> Or something like that.

Yes.  Unfortunately, (ifdef baz '((setq bar 2))) doesn't produce a
valid form when baz is not nil.  When it is used outside of a macro,
that produces an error.  This is not a good property.  It would be
better to keep the contract of macros, that is they take code, and
they produce code, that is, valid forms.  This can be done if you wrap
the body in a progn when baz is not nil.

(defmacro ifdef (expr &rest body)
  (if (eval expr)
     'nil   
     `(progn ,@body)))

(require 'cl) ; as usual

(defmacro titi (fn)
   `(defun ,fn ()
       (setq bar 1)
       ,@(let ((form (macroexpand '(ifdef baz (setq bar 2)))))
           (and form `(,form)))))

(dolist (baz '(nil t))
  (print (macroexpand '(titi foo))))

(defun foo nil (setq bar 1) (progn (setq bar 2)))

(defun foo nil (setq bar 1))
nil

Notice that (defun foo nil (setq bar 1) (progn (setq bar 2))) and 
(defun foo nil (setq bar 1) (setq bar 2)) compile to exactly the same.


-- 
__Pascal Bourguignon__


^ permalink raw reply	[flat|nested] 43+ messages in thread

* RE: Is it possible for a macro to expand to nothing?
  2009-11-23 18:33     ` Pascal J. Bourguignon
@ 2009-11-23 18:51       ` Drew Adams
       [not found]       ` <mailman.11354.1259004470.2239.help-gnu-emacs@gnu.org>
  1 sibling, 0 replies; 43+ messages in thread
From: Drew Adams @ 2009-11-23 18:51 UTC (permalink / raw
  To: 'Pascal J. Bourguignon', help-gnu-emacs

> >> you can do that by producing nil and then using ,@ inside a
> >> backquote. IOW, instead of inserting nil, you splice it in,
> >> which means inserting nothing.

> That wouldn't work, backquote is a quote.

Sorry, but it works just fine. I do this all the time.

You snipped out the code I suggested. Here it is again, with `and' substituted
for `ifdef' (which is undefined).

(defmacro titi (fn)
  `(defun ,fn ()
    (setq bar 1)
    ,@(and baz '((setq bar 2)))))

(let ((baz nil)) (titi foo))
(symbol-function 'foo) -> (lambda nil (setq bar 1))

(let ((baz t)) (titi foo))
(symbol-function 'foo) ->
  (lambda nil
    (setq bar 1)
    (setq bar 2))

That looks to me like just what Alan asked for.





^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: Is it possible for a macro to expand to nothing?
       [not found]       ` <mailman.11354.1259004470.2239.help-gnu-emacs@gnu.org>
@ 2009-11-23 20:08         ` Pascal J. Bourguignon
  2009-11-23 20:24           ` Alan Mackenzie
                             ` (2 more replies)
  0 siblings, 3 replies; 43+ messages in thread
From: Pascal J. Bourguignon @ 2009-11-23 20:08 UTC (permalink / raw
  To: help-gnu-emacs

"Drew Adams" <drew.adams@oracle.com> writes:

>> >> you can do that by producing nil and then using ,@ inside a
>> >> backquote. IOW, instead of inserting nil, you splice it in,
>> >> which means inserting nothing.
>
>> That wouldn't work, backquote is a quote.
>
> Sorry, but it works just fine. I do this all the time.

No, it doesn't:

(defmacro ifdef (expr &rest body)
   (and (eval expr) `(progn ,@body)))

(ifdef t ((setq bar 2)))
-->
Debugger entered--Lisp error: (invalid-function (setq bar 2))
  ((setq bar 2))
  (progn ((setq bar 2)))
  (ifdef t ((setq bar 2)))
  eval((ifdef t ((setq bar 2))))
  eval-last-sexp-1((4))
  eval-last-sexp((4))
  call-interactively(eval-last-sexp)


> You snipped out the code I suggested. Here it is again, with `and' substituted
> for `ifdef' (which is undefined).
>
> (defmacro titi (fn)

I didn't say that it didn't work inside titi.  I said that it was a
bad idea to take the habit of giving an invalid form to a macro to
get an invalid form from it.




Notice also my alternative solution uses macroexpand.   This is a clue
that if you want to go that way, you should use a function rather than
a macro:

   (defun %parenthesized-ifdef (expr forms)
      (if expr
          '()
          `((progn ,@forms))))

   (defmacro titi (fn)
      `(defun ,fn  ()
          (setq bar 1)
          ,@(%parenthesized-ifdef baz '((setq bar 2)))))

(macroexpand '(titi foo))
--> (defun foo nil (setq bar 1) (progn (setq bar 2)))



-- 
__Pascal Bourguignon__


^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: Is it possible for a macro to expand to nothing?
       [not found]     ` <mailman.11352.1258997403.2239.help-gnu-emacs@gnu.org>
  2009-11-23 18:42       ` Pascal J. Bourguignon
@ 2009-11-23 20:09       ` Alan Mackenzie
  1 sibling, 0 replies; 43+ messages in thread
From: Alan Mackenzie @ 2009-11-23 20:09 UTC (permalink / raw
  To: help-gnu-emacs

Hi, Drew!

Drew Adams <drew.adams@oracle.com> wrote:
>> I think I want to be able to do this:

>>     (defun foo ()
>>       (setq bar 1)
>>       (ifdef baz (setq bar 2)))

>> , and if baz is nil at compile time, this function should be 
>> identical to

>>     (defun foo ()
>>       (setq bar 1))

> (defmacro titi (fn)
>  `(defun ,fn ()
>     (setq bar 1)
>     ,@(ifdef baz '((setq bar 2))))))

> Assuming that ifdef returns nil if baz is nil, that should give you
> (defun foo () (setq bar 1)). If baz is not nil, it should give you
> this:

> (defun foo ()
> (setq bar 1)
> (setq bar 2))

> Or something like that.

Wow, you're a genius, Drew!  It's a little bit ugly having to write a
defmacro around a defun, but only a very very little.

The way you've described actually looks fairly obviousi now, but these
things always do after somebody bright has just shown you them.

Thanks again!

-- 
Alan Mackenzie (Nuremberg, Germany).



^ permalink raw reply	[flat|nested] 43+ messages in thread

* RE: Is it possible for a macro to expand to nothing?
  2009-11-23 18:42       ` Pascal J. Bourguignon
@ 2009-11-23 20:12         ` Drew Adams
       [not found]         ` <mailman.11356.1259007263.2239.help-gnu-emacs@gnu.org>
  1 sibling, 0 replies; 43+ messages in thread
From: Drew Adams @ 2009-11-23 20:12 UTC (permalink / raw
  To: 'Pascal J. Bourguignon', help-gnu-emacs

> > (defmacro titi (fn)
> >   `(defun ,fn ()
> >      (setq bar 1)
> >      ,@(ifdef baz '((setq bar 2))))))
> >
> > Assuming that ifdef returns nil if baz is nil, that should 
> > give you (defun foo () (setq bar 1)). If baz is not nil,
> > it should give you this:
> >
> > (defun foo ()
> >  (setq bar 1)
> >  (setq bar 2))
> 
> Yes.  Unfortunately, (ifdef baz '((setq bar 2))) doesn't produce a
> valid form when baz is not nil.

Huh? It produces the list ((setq bar 2)), assuming `ifdef' acts like `and'
(`ifdef' is undefined AFAIK).

((setq bar 2)) is then spliced in, because of ,@.
And that produces the requested code.

> When it is used outside of a macro, that produces an error.

'((setq bar 2)) produces the list ((setq bar 2)) anywhere you evaluate it.

> This is not a good property.  It would be
> better to keep the contract of macros, that is they take code, and
> they produce code, that is, valid forms.

No idea what you are talking about.

It's simple, really: The code resulting from macroexpansion is a list. Just
splice a list into the list you are building, instead of adding an element to
it. If the list you splice in is (), then nothing is added to the list.

(setq a1 '(M)  a2 ())
(macroexpand `(x ,@a1)) = (x M)
(macroexpand `(x ,@a2)) = (x)

That's really all there is to it: instead of trying to add or not add M, splice
in (M) or ().





^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: Is it possible for a macro to expand to nothing?
       [not found]         ` <mailman.11356.1259007263.2239.help-gnu-emacs@gnu.org>
@ 2009-11-23 20:21           ` Pascal J. Bourguignon
  2009-11-23 22:09             ` Drew Adams
       [not found]             ` <mailman.11368.1259014177.2239.help-gnu-emacs@gnu.org>
  0 siblings, 2 replies; 43+ messages in thread
From: Pascal J. Bourguignon @ 2009-11-23 20:21 UTC (permalink / raw
  To: help-gnu-emacs

"Drew Adams" <drew.adams@oracle.com> writes:

>> > (defmacro titi (fn)
>> >   `(defun ,fn ()
>> >      (setq bar 1)
>> >      ,@(ifdef baz '((setq bar 2))))))
>> >
>> > Assuming that ifdef returns nil if baz is nil, that should 
>> > give you (defun foo () (setq bar 1)). If baz is not nil,
>> > it should give you this:
>> >
>> > (defun foo ()
>> >  (setq bar 1)
>> >  (setq bar 2))
>> 
>> Yes.  Unfortunately, (ifdef baz '((setq bar 2))) doesn't produce a
>> valid form when baz is not nil.
>
> Huh? It produces the list ((setq bar 2)), assuming `ifdef' acts like `and'
> (`ifdef' is undefined AFAIK).

Yes.  And ((setq bar 2)) is not a valid form.  So it is not a good
idea, not a good style to call (ifdef baz '((setq bar 2))) and use its
result like that.


>> This is not a good property.  It would be
>> better to keep the contract of macros, that is they take code, and
>> they produce code, that is, valid forms.
>
> No idea what you are talking about.

Yes, that's the problem.


> It's simple, really: The code resulting from macroexpansion is a list. 

No.  CODE resulting from macroexpansion should be CODE.  Not just a list.
If you want to get random lists, then use functions, not macros.  


-- 
__Pascal Bourguignon__


^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: Is it possible for a macro to expand to nothing?
  2009-11-23 20:08         ` Pascal J. Bourguignon
@ 2009-11-23 20:24           ` Alan Mackenzie
  2009-11-23 22:09           ` Drew Adams
       [not found]           ` <mailman.11367.1259014174.2239.help-gnu-emacs@gnu.org>
  2 siblings, 0 replies; 43+ messages in thread
From: Alan Mackenzie @ 2009-11-23 20:24 UTC (permalink / raw
  To: help-gnu-emacs

Pascal J. Bourguignon <pjb@informatimago.com> wrote:
> "Drew Adams" <drew.adams@oracle.com> writes:

>>> >> you can do that by producing nil and then using ,@ inside a
>>> >> backquote. IOW, instead of inserting nil, you splice it in,
>>> >> which means inserting nothing.

>>> That wouldn't work, backquote is a quote.

>> Sorry, but it works just fine. I do this all the time.

> No, it doesn't:

It worked fine for me.

> (defmacro ifdef (expr &rest body)
>   (and (eval expr) `(progn ,@body)))

My definition of `ifdef' is:

    (defmacro ifdef (condition form)
      (if (eval condition)
          `,form))

, which though lacking an &rest argument, could easily be enhanced to
take one.

[ .... ]

> I didn't say that it didn't work inside titi.  I said that it was a bad
> idea to take the habit of giving an invalid form to a macro to get an
> invalid form from it.

If the form doesn't cause a runtime error, it's not invalid.  ;-) The
reason I want this functionality is to optimise a VERY VERY tight loop.
I believe that the optimisation isn't feasible under XEmacs, so I want to
be able to put things for XEmacs inside Lisp equivalents of "#ifdef".
Even inserting an invocation of `(ignore)' seems to make a difference.
As far as I remember, anyway.  With Drew's mechanism, one doesn't have to
rely on the byte-compiler optimising an empty `progn' or a frivolous
`progn' away.

> Notice also my alternative solution uses macroexpand.   This is a clue
> that if you want to go that way, you should use a function rather than
> a macro:

>   (defun %parenthesized-ifdef (expr forms)
>      (if expr
>          '()
>          `((progn ,@forms))))

>   (defmacro titi (fn)
>      `(defun ,fn  ()
>          (setq bar 1)
>          ,@(%parenthesized-ifdef baz '((setq bar 2)))))

> (macroexpand '(titi foo))
> --> (defun foo nil (setq bar 1) (progn (setq bar 2)))

Yes, but that `progn' is ugly.

-- 
Alan Mackenzie (Nuremberg, Germany).



^ permalink raw reply	[flat|nested] 43+ messages in thread

* RE: Is it possible for a macro to expand to nothing?
  2009-11-23 20:08         ` Pascal J. Bourguignon
  2009-11-23 20:24           ` Alan Mackenzie
@ 2009-11-23 22:09           ` Drew Adams
       [not found]           ` <mailman.11367.1259014174.2239.help-gnu-emacs@gnu.org>
  2 siblings, 0 replies; 43+ messages in thread
From: Drew Adams @ 2009-11-23 22:09 UTC (permalink / raw
  To: 'Pascal J. Bourguignon', help-gnu-emacs

> > Sorry, but it works just fine. I do this all the time.
> 
> No, it doesn't:
> (defmacro ifdef (expr &rest body)
>    (and (eval expr) `(progn ,@body)))
> (ifdef t ((setq bar 2)))
> Debugger entered--Lisp error: (invalid-function (setq bar 2))

You seem to be complaining about yourself. I never suggested using such a macro.

All I suggested was to use backquote with ,@ to splice in a list with the
element that Alan conditionally wants in the macroexpansion. That's the way to
add something or nothing to a list: put the something or nothing in a list, then
splice in that list.

The list to be built here is a defun expression. It is then evaluated without
problem.

> I said that it was a bad idea to take the habit of giving
> an invalid form to a macro to get an invalid form from it.

Sorry, dunno what you're saying. There wasn't anything invalid in what I
suggested.

As far as I'm concerned, all that's really involved is writing a macro that
expands to a list that contains or doesn't contain the element in question. Any
such list is a valid _list_.

When the list resulting from macroexpansion is then EVALUATED, yes, of course
its car must be a defined function, macro, `lambda', etc. (or the list must be
nil). That is an entirely different matter. That is a consideration for _any_
macro one writes.

In Alan's case, the resulting list has `defun' as its car. It is a valid defun
expression whose evaluation defines a function.

The only thing relevant here, AFAICT, is how to create the list Alan wants: a
list that conditionally contains some element. Backquote plus ,@ is the answer.

> Notice also my alternative solution uses macroexpand.   This is a clue
> that if you want to go that way, you should use a function rather than
> a macro:
>    (defun %parenthesized-ifdef (expr forms)
>       (if expr
>           '()
>           `((progn ,@forms))))
>    (defmacro titi (fn)
>       `(defun ,fn  ()
>           (setq bar 1)
>           ,@(%parenthesized-ifdef baz '((setq bar 2)))))
> 
> (macroexpand '(titi foo))
> --> (defun foo nil (setq bar 1) (progn (setq bar 2)))

Dunno why you do all that. Just `,@forms is as useful here as `((progn ,@forms))
- a defun body is an implicit progn. (And there is no need to quote nil.)

Again, all of that code boils down to just this (which is what I wrote earlier):

(defmacro titi (fn)
  `(defun ,fn ()
    (setq bar 1)
    ,@(and baz '((setq bar 2)))))

I'm sure you know what you're talking about, and I know what I'm talking about
;-). The only real question is whether either of us has actually helped Alan at
all.





^ permalink raw reply	[flat|nested] 43+ messages in thread

* RE: Is it possible for a macro to expand to nothing?
  2009-11-23 20:21           ` Pascal J. Bourguignon
@ 2009-11-23 22:09             ` Drew Adams
       [not found]             ` <mailman.11368.1259014177.2239.help-gnu-emacs@gnu.org>
  1 sibling, 0 replies; 43+ messages in thread
From: Drew Adams @ 2009-11-23 22:09 UTC (permalink / raw
  To: 'Pascal J. Bourguignon', help-gnu-emacs

> > Huh? It produces the list ((setq bar 2)), assuming `ifdef' 
> > acts like `and'
> 
> Yes.  And ((setq bar 2)) is not a valid form.

Of course it's valid - it's a list.

Perhaps you are trying to _evaluate_ it? What you should be evaluating is the
entire list that results from macroexpanding the defmacro body. That list is a
defun sexp in Alan's case, and there is no problem evaluating it.

> So it is not a good idea, not a good style...
> 
> >> This is not a good property.  It would be
> >> better to keep the contract of macros, that is they take code, and
> >> they produce code, that is, valid forms.
> >
> > No idea what you are talking about.
> 
> Yes, that's the problem.
> 
> > It's simple, really: The code resulting from macroexpansion 
> > is a list.
> 
> No.  CODE resulting from macroexpansion should be CODE.  Not 
> just a list. If you want to get random lists, then use functions,
> not macros.  

The CODE resulting from the macroexpansion here is a _list_ whose car is
`defun'. It is a perfectly valid defun expression that can be evaluated without
error. It is CODE.

But the fact that the body of a defmacro should macroexpand to something that
can be evaluated without error is just background info. It is true for all
macros. It has nothing to do with the specific question Alan raised.

[And BTW, a sexp whose evaluation raises an error is not necessarily "invalid".
Validation requires validation against something (e.g. a syntax definition or a
specification). Lisp _syntax_ can be said to be invalid if it raises a read-time
error. But just because evaluating a sexp raises an error doesn't mean the
syntax is invalid. The list (bar) is not "invalid" if evaluating it raises the
error that bar's function definition is void.]





^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: Is it possible for a macro to expand to nothing?
       [not found]           ` <mailman.11367.1259014174.2239.help-gnu-emacs@gnu.org>
@ 2009-11-23 23:55             ` Pascal J. Bourguignon
  2009-11-24  0:55               ` Alan Mackenzie
  0 siblings, 1 reply; 43+ messages in thread
From: Pascal J. Bourguignon @ 2009-11-23 23:55 UTC (permalink / raw
  To: help-gnu-emacs

"Drew Adams" <drew.adams@oracle.com> writes:

>> > Sorry, but it works just fine. I do this all the time.
>> 
>> No, it doesn't:
>> (defmacro ifdef (expr &rest body)
>>    (and (eval expr) `(progn ,@body)))
>> (ifdef t ((setq bar 2)))
>> Debugger entered--Lisp error: (invalid-function (setq bar 2))
>
> You seem to be complaining about yourself. I never suggested using such a macro.
>
> All I suggested was to use backquote with ,@ to splice in a list with the
> element that Alan conditionally wants in the macroexpansion. That's the way to
> add something or nothing to a list: put the something or nothing in a list, then
> splice in that list.
>
> The list to be built here is a defun expression. It is then evaluated without
> problem.
>
>> I said that it was a bad idea to take the habit of giving
>> an invalid form to a macro to get an invalid form from it.
>
> Sorry, dunno what you're saying. There wasn't anything invalid in what I
> suggested.
>
> As far as I'm concerned, all that's really involved is writing a macro that
> expands to a list that contains or doesn't contain the element in question. Any
> such list is a valid _list_.

This is the problem!  Macros shouldn't return a _list_, they should
return a _form_.  If you write a macro that returns a list, or you use
it so that it returns a list, that is not a valid form, then it is not
good style, even if you catch up.


> When the list resulting from macroexpansion is then EVALUATED, yes, of course
> its car must be a defined function, macro, `lambda', etc. (or the list must be
> nil). That is an entirely different matter. That is a consideration for _any_
> macro one writes.
>
> In Alan's case, the resulting list has `defun' as its car. It is a valid defun
> expression whose evaluation defines a function.

I don't mind titi, I  object to your use of ifdef in titi.  That ifdef
call returns a list that is not a valid form.  This is not good style.



> The only thing relevant here, AFAICT, is how to create the list Alan wants: a
> list that conditionally contains some element. Backquote plus ,@ is the answer.

Yes, since you only want to create a list at that point, do not use a
macro, use a function.


>> Notice also my alternative solution uses macroexpand.   This is a clue
>> that if you want to go that way, you should use a function rather than
>> a macro:
>>    (defun %parenthesized-ifdef (expr forms)
>>       (if expr
>>           '()
>>           `((progn ,@forms))))
>>    (defmacro titi (fn)
>>       `(defun ,fn  ()
>>           (setq bar 1)
>>           ,@(%parenthesized-ifdef baz '((setq bar 2)))))
>> 
>> (macroexpand '(titi foo))
>> --> (defun foo nil (setq bar 1) (progn (setq bar 2)))
>
> Dunno why you do all that. 

Because it is a better style.  It avoids abusing the ifdef macro.


> (And there is no need to quote nil.)

There are again very good stylistic reasons to quote nil or ()
depending on the case.


> Again, all of that code boils down to just this (which is what I wrote earlier):
>
> (defmacro titi (fn)
>   `(defun ,fn ()
>     (setq bar 1)
>     ,@(and baz '((setq bar 2)))))

I'm OK with this version (since it doesn't abuse the ifdef macro).


> I'm sure you know what you're talking about, and I know what I'm
> talking about ;-). The only real question is whether either of us
> has actually helped Alan at all.

Well, he has a lot of solutions to choose from now.  Indeed, his
situation may not be better :-)

-- 
__Pascal Bourguignon__


^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: Is it possible for a macro to expand to nothing?
       [not found]             ` <mailman.11368.1259014177.2239.help-gnu-emacs@gnu.org>
@ 2009-11-24  0:03               ` Pascal J. Bourguignon
  0 siblings, 0 replies; 43+ messages in thread
From: Pascal J. Bourguignon @ 2009-11-24  0:03 UTC (permalink / raw
  To: help-gnu-emacs

"Drew Adams" <drew.adams@oracle.com> writes:

>> > Huh? It produces the list ((setq bar 2)), assuming `ifdef' 
>> > acts like `and'
>> 
>> Yes.  And ((setq bar 2)) is not a valid form.
>
> Of course it's valid - it's a list.

I'm using this definition:

  form n. 
    1. any object meant to be evaluated. 
    2. a symbol, a compound form, or a  self-evaluating object. 
    3. (for an operator, as in ``<<operator>> form'') a compound form
    having that operator as its first element. ``A quote form is a
    constant form.''

(eval '((setq bar 2)))
--> Debugger entered--Lisp error: (invalid-function (setq bar 2))

Therefore ((setq bar 2)) is not valid form.


> Perhaps you are trying to _evaluate_ it? 

Yes, that's what the result of macro calls should, at leat
potentially, be done with.


> [And BTW, a sexp whose evaluation raises an error is not necessarily "invalid".
> Validation requires validation against something (e.g. a syntax definition or a
> specification). Lisp _syntax_ can be said to be invalid if it raises a read-time
> error. But just because evaluating a sexp raises an error doesn't mean the
> syntax is invalid. The list (bar) is not "invalid" if evaluating it raises the
> error that bar's function definition is void.]

If that was the case, then in a protected environment like lisp,
everything is valid, as long as we don't stumble upon a crashing bug
in the implementation.

But it is more useful to distinguish forms doing something useful for
the user or programmers from those signaling errors systematically,
because of their intrinsic nature (because they're invalid forms).
 

-- 
__Pascal Bourguignon__


^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: Is it possible for a macro to expand to nothing?
  2009-11-23 23:55             ` Pascal J. Bourguignon
@ 2009-11-24  0:55               ` Alan Mackenzie
  2009-11-24  9:42                 ` Pascal J. Bourguignon
  0 siblings, 1 reply; 43+ messages in thread
From: Alan Mackenzie @ 2009-11-24  0:55 UTC (permalink / raw
  To: help-gnu-emacs

Pascal J. Bourguignon <pjb@informatimago.com> wrote:
> "Drew Adams" <drew.adams@oracle.com> writes:

> This is the problem!  Macros shouldn't return a _list_, they should
> return a _form_.  If you write a macro that returns a list, or you use
> it so that it returns a list, that is not a valid form, then it is not
> good style, even if you catch up.

Is that right?  I think you should be required to justify this assertion
of "good style".  If that "good style" really is good style, then the
whole of cc-langs.el (which uses intense macro magic to generate data
structures with both compile-time and run-time behaviour) is attrocious
style.  Fact is, though, it allows a simple tabular writing of constants
which vary between C, C++, java, ....  Kudos to Martin Stjernholm, who
wrote it.

>> When the list resulting from macroexpansion is then EVALUATED, yes, of
>> course its car must be a defined function, macro, `lambda', etc. (or
>> the list must be nil). That is an entirely different matter. That is a
>> consideration for _any_ macro one writes.

>> In Alan's case, the resulting list has `defun' as its car. It is a
>> valid defun expression whose evaluation defines a function.

> I don't mind titi, I object to your use of ifdef in titi.  That ifdef
> call returns a list that is not a valid form.  This is not good style.

I was more than happy with it.  The form was valid, for a reasonable
value of "form", and worked.

>> The only thing relevant here, AFAICT, is how to create the list Alan
>> wants: a list that conditionally contains some element. Backquote plus
>> ,@ is the answer.

> Yes, since you only want to create a list at that point, do not use a
> macro, use a function.

Sounds like a fair alternative.  Though it's too late at night for my
head to work round whether or not a mere function could do the job in the
general case.

[ .... ]

>> Dunno why you do all that. 

> Because it is a better style.  It avoids abusing the ifdef macro.

Where does this notion of "abuse" come from?  What is its rationale?
(This is a genuine question.)


>> I'm sure you know what you're talking about, and I know what I'm
>> talking about ;-). The only real question is whether either of us
>> has actually helped Alan at all.

> Well, he has a lot of solutions to choose from now.  Indeed, his
> situation may not be better :-)

Yes, I feel I have been helped.  Thank you, both, and good night!

-- 
Alan Mackenzie (Nuremberg, Germany).



^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: Is it possible for a macro to expand to nothing?
  2009-11-24  0:55               ` Alan Mackenzie
@ 2009-11-24  9:42                 ` Pascal J. Bourguignon
  2009-11-24 10:45                   ` Alan Mackenzie
  0 siblings, 1 reply; 43+ messages in thread
From: Pascal J. Bourguignon @ 2009-11-24  9:42 UTC (permalink / raw
  To: help-gnu-emacs

Alan Mackenzie <acm@muc.de> writes:

> Pascal J. Bourguignon <pjb@informatimago.com> wrote:
>> "Drew Adams" <drew.adams@oracle.com> writes:
>
>> This is the problem!  Macros shouldn't return a _list_, they should
>> return a _form_.  If you write a macro that returns a list, or you use
>> it so that it returns a list, that is not a valid form, then it is not
>> good style, even if you catch up.
>
> Is that right?  I think you should be required to justify this assertion
> of "good style".  If that "good style" really is good style, then the
> whole of cc-langs.el (which uses intense macro magic to generate data
> structures with both compile-time and run-time behaviour) is attrocious
> style.  

If that was the case, yes, I would think so.  Macros are designed to
generate code, not other data.  If you are generating general data,
then using functions will be easier and clearer.

But cc-langs.el only defines four macros and they all generate
perfectly good lisp code.


> Fact is, though, it allows a simple tabular writing of constants
> which vary between C, C++, java, ....  Kudos to Martin Stjernholm, who
> wrote it.

Unfortunately, most of emacs lisp code is bad code.  Functions one
kilometer long, chained with one or more others one kilometer long.
Copy-and-pasted chunks instead of abstracting it away.  Etc.

I cannot say that I've read a significant percentage of it, but the
code I had to peek at in my 20 years of use of emacs, I cannot say I
was impressionned by its good quality...

Now of course, I had a peek at code that had bugs or missing features
in the first place.  Perhaps the good quality emacs lisp code I hadn't
a peek at because it worked well enough so I didn't need to.


>> Because it is a better style.  It avoids abusing the ifdef macro.
>
> Where does this notion of "abuse" come from?  What is its rationale?
> (This is a genuine question.)

The general contract of a macro is that it returns valid forms.

In all fairness,  ifdef does return valid forms, when provided valid
forms as argument.

(defmacro ifdef (expr &rest body)
   (and (eval expr) `(progn ,@body)))

(ifdef t (setq bar 2))
--> 2

It's only when provided invalid argu-ment that it returns an invalid
form:

(ifdef t ((setq bar 2)))
--> Debugger entered--Lisp error: (invalid-function (setq bar 2))


The fact that such a macro call embedded in another form building form
that processes it properly doesn't mean that it is not bad style: it
has to do something special to the result of ifdef to make it work.
If you extract that ifdef call to run it at the repl, it just cannot
work.


-- 
__Pascal Bourguignon__


^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: Is it possible for a macro to expand to nothing?
  2009-11-24  9:42                 ` Pascal J. Bourguignon
@ 2009-11-24 10:45                   ` Alan Mackenzie
  2009-11-24 11:14                     ` Pascal J. Bourguignon
  2009-11-24 11:56                     ` Pascal J. Bourguignon
  0 siblings, 2 replies; 43+ messages in thread
From: Alan Mackenzie @ 2009-11-24 10:45 UTC (permalink / raw
  To: help-gnu-emacs

Pascal J. Bourguignon <pjb@informatimago.com> wrote:
> Alan Mackenzie <acm@muc.de> writes:

>> Pascal J. Bourguignon <pjb@informatimago.com> wrote:
>>> "Drew Adams" <drew.adams@oracle.com> writes:

>>> This is the problem!  Macros shouldn't return a _list_, they should
>>> return a _form_.  If you write a macro that returns a list, or you
>>> use it so that it returns a list, that is not a valid form, then it
>>> is not good style, even if you catch up.

>> Is that right?  I think you should be required to justify this
>> assertion of "good style".  If that "good style" really is good style,
>> then the whole of cc-langs.el (which uses intense macro magic to
>> generate data structures with both compile-time and run-time
>> behaviour) is attrocious style.

> If that was the case, yes, I would think so.  Macros are designed to
> generate code, not other data.

I'm no lisp guru, but I must disagree strongly with this.  What is code,
what is data?  Surely they are essentiallty the same, particularly in
lisp.  You would hold that a macro which generates a font-lock-defaults
structure (so as to reduce the tedium of doing it by hand) is an abuse of
the macro idea, would you?

> If you are generating general data, then using functions will be easier
> and clearer.

If it's possible.  But if this were the case, using functions to generate
"code" would be easier and clearer, too.

> But cc-langs.el only defines four macros and they all generate
> perfectly good lisp code.

Any macro, once debugged, generates "perfectly good" lisp code.  I don't
understand where this notion of "perfectly good" comes from.

>> Fact is, though, it allows a simple tabular writing of constants which
>> vary between C, C++, java, ....  Kudos to Martin Stjernholm, who wrote
>> it.

> Unfortunately, most of emacs lisp code is bad code.  Functions one
> kilometer long, chained with one or more others one kilometer long.
> Copy-and-pasted chunks instead of abstracting it away.  Etc.

I can't disagree with that, sadly.  However I think Emacs's code base is
better than a typical 25 yo application still under development (if there
is such a beast).

> Now of course, I had a peek at code that had bugs or missing features
> in the first place.  Perhaps the good quality emacs lisp code I hadn't
> a peek at because it worked well enough so I didn't need to.

Perhaps.

>>> Because it is a better style.  It avoids abusing the ifdef macro.

>> Where does this notion of "abuse" come from?  What is its rationale?
>> (This is a genuine question.)

> The general contract of a macro is that it returns valid forms.

Sorry, Pascal, you're just restating the same thing again, not answering
my question.  Why should I accept this "general contract of a macro"?  I
haven't signed it.  ;-)  Is there some respected Lisp guru who says this?
What would this guru say about the macro which generates a
font-lock-defaults structure?

> In all fairness, ifdef does return valid forms, when provided valid
> forms as argument.

> (defmacro ifdef (expr &rest body)
>   (and (eval expr) `(progn ,@body)))

That version of ifdef is ugly because it contains an obtrusive `progn'.
The version I used doesn't.  There is no guarantee that a lisp compiler,
particularly the Emacs lisp byte compiler, is going to optimise away this
unnecessary artifact.  It seems this `progn' is there purely to satisfy
the (as yet unsubstantiated) injunction to return only "perfectly good"
lisp forms.

> The fact that such a macro call embedded in another form building form
> that processes it properly doesn't mean that it is not bad style: it
> has to do something special to the result of ifdef to make it work.
> If you extract that ifdef call to run it at the repl, it just cannot
> work.

Yes.

-- 
Alan Mackenzie (Nuremberg, Germany).



^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: Is it possible for a macro to expand to nothing?
  2009-11-24 10:45                   ` Alan Mackenzie
@ 2009-11-24 11:14                     ` Pascal J. Bourguignon
  2009-11-24 16:39                       ` Alan Mackenzie
  2009-11-24 11:56                     ` Pascal J. Bourguignon
  1 sibling, 1 reply; 43+ messages in thread
From: Pascal J. Bourguignon @ 2009-11-24 11:14 UTC (permalink / raw
  To: help-gnu-emacs

Alan Mackenzie <acm@muc.de> writes:

> Pascal J. Bourguignon <pjb@informatimago.com> wrote:
>> Alan Mackenzie <acm@muc.de> writes:
>
>>> Pascal J. Bourguignon <pjb@informatimago.com> wrote:
>>>> "Drew Adams" <drew.adams@oracle.com> writes:
>
>>>> This is the problem!  Macros shouldn't return a _list_, they should
>>>> return a _form_.  If you write a macro that returns a list, or you
>>>> use it so that it returns a list, that is not a valid form, then it
>>>> is not good style, even if you catch up.
>
>>> Is that right?  I think you should be required to justify this
>>> assertion of "good style".  If that "good style" really is good style,
>>> then the whole of cc-langs.el (which uses intense macro magic to
>>> generate data structures with both compile-time and run-time
>>> behaviour) is attrocious style.
>
>> If that was the case, yes, I would think so.  Macros are designed to
>> generate code, not other data.
>
> I'm no lisp guru, but I must disagree strongly with this.  What is code,
> what is data?  Surely they are essentiallty the same, particularly in
> lisp.  You would hold that a macro which generates a font-lock-defaults
> structure (so as to reduce the tedium of doing it by hand) is an abuse of
> the macro idea, would you?

There is an essential difference between "code" and "data".

I won't define data, let's take it as axiom.

Code is a kind of data, for which there exist a processor.  Of course,
you can always produce a processor to handle any kind of data:

  (defun data-processor (data)
      data)

Lisp code is the kind of data that is accepted by eval.

Valid lisp code is the kind of lisp code that eval can process and
return the result without signaling an error (it can signal errors
internally, if they are caught).


Valid Zorblug code is Zorblug code that zorbluyg can process and
return the result without signaling an error.

(defun zorblug (form)
   (if (listp form)
     (apply (function +) (mapcar (function zorblug) form))
     (error "Not a zorblug form %S" form)))

(zorblug 42)
--> Debugger entered--Lisp error: (error "Not a zorblug form 42")

(zorblug '(nil (nil nil) nil))
--> 0


        data    valid Zorblug code      Lisp code        Valid lisp code
42      yes            no                 yes                 yes
(nil)   yes           yes                 yes                  no
(+ 1 2) yes            no                 yes                 yes
(/ 1 0) yes            no                 yes                  no

My claim is that it is not a good style to write a macro that produces
non valid lisp code, because lisp macros are designed to produce code
that will be evaluated by the lisp eval, not by the zorblug processor
or any other random data processor. (There may be an exception, where
a macro generate lisp code that signal an error, if this is the
specific purpose of the macro; but for a normal macro, it is better if
it generates only valid lisp code).


If you want to transform code for other processors, or random data,
use functions.


Notice that the above data-processor doesn't use lisp macros.  You
could try to hook lisp macros in the data-processor, but this would be
bad style, and it would probably be easier and safer (namespace wise)
to just write your own data macro system, since implementing one is
rather trivial.



>> If you are generating general data, then using functions will be easier
>> and clearer.
>
> If it's possible.  But if this were the case, using functions to generate
> "code" would be easier and clearer, too.

Absolutely.  And more useful in some circumstances too.  That's why
you should write non trivial macros as a mere call to the code
generating function:

(defmacro non-trivial-macro (arguments...)
   (generate-non-trivial-code arguments...))



>> But cc-langs.el only defines four macros and they all generate
>> perfectly good lisp code.
>
> Any macro, once debugged, generates "perfectly good" lisp code.  I don't
> understand where this notion of "perfectly good" comes from.

It means valid lisp code, see definition above.


>>> Fact is, though, it allows a simple tabular writing of constants which
>>> vary between C, C++, java, ....  Kudos to Martin Stjernholm, who wrote
>>> it.
>
>> Unfortunately, most of emacs lisp code is bad code.  Functions one
>> kilometer long, chained with one or more others one kilometer long.
>> Copy-and-pasted chunks instead of abstracting it away.  Etc.
>
> I can't disagree with that, sadly.  However I think Emacs's code base is
> better than a typical 25 yo application still under development (if there
> is such a beast).

Yes, the fact that it still runs, is still useful, and can still be
maintained despite these bad parts is proof of it, that it's better
than typical 25 yo or even a lot of much younger programs.


>> Now of course, I had a peek at code that had bugs or missing features
>> in the first place.  Perhaps the good quality emacs lisp code I hadn't
>> a peek at because it worked well enough so I didn't need to.
>
> Perhaps.
>
>>>> Because it is a better style.  It avoids abusing the ifdef macro.
>
>>> Where does this notion of "abuse" come from?  What is its rationale?
>>> (This is a genuine question.)
>
>> The general contract of a macro is that it returns valid forms.
>
> Sorry, Pascal, you're just restating the same thing again, not answering
> my question.  Why should I accept this "general contract of a macro"?  I
> haven't signed it.  ;-)  Is there some respected Lisp guru who says this?

It comes directly from the definition of defmacro,

    defmacro is a special form in `src/eval.c'.
    (defmacro name arglist [docstring] [decl] body...)

    Define name as a macro.
    The actual definition looks like
     (macro lambda arglist [docstring] [decl] body...).
    When the macro is called, as in (name ARGS...),
    the function (lambda arglist body...) is applied to
    the list ARGS... as it appears in the expression,
    and the result should be a form to be evaluated instead of the original.

(for the definition of form, see the Common Lisp glossary entry I
quoted elsewhere in this thread).

> What would this guru say about the macro which generates a
> font-lock-defaults structure?

If this structure cannot be passed to eval without signaling an error,
then I would say that it is bad style to use a macro to generate such
data.



>> In all fairness, ifdef does return valid forms, when provided valid
>> forms as argument.
>
>> (defmacro ifdef (expr &rest body)
>>   (and (eval expr) `(progn ,@body)))
>
> That version of ifdef is ugly because it contains an obtrusive `progn'.

In a way here, progn is the dual of list.

When you want to generate a list of data, you use list:

  `(list  ,expr1 ,expr2 ... ,exprN)

When you want to generate a list of code, you use progn:

  `(progn ,form1 ,form2 ... ,formN)


It is not obtrusive in any way, it only shows that we are generating
code, not mere data.


> The version I used doesn't.  There is no guarantee that a lisp compiler,
> particularly the Emacs lisp byte compiler, is going to optimise away this
> unnecessary artifact.  

All lisp compilers will obviously optimize out embedded progn forms,
because no object code can correspond to it.

(disassemble (byte-compile '(lambda () (progn (progn (progn) (progn)) (progn)))))
-->
byte code:
  args: nil
0       constant  nil
1       return    

They would optimize out similarly unneeded forms:
(disassemble (byte-compile '(lambda () nil nil nil nil nil)))
produces the same byte code as above.



> It seems this `progn' is there purely to satisfy
> the (as yet unsubstantiated) injunction to return only "perfectly good"
> lisp forms.

Not 'purely'.  You could optimize it out when unnecessary with:

  (defun progn-encapsulate (forms)
    (if (= 1 (length forms)) 
       (first forms)
       (list* 'progn forms)))

  (defmacro ifdef (expr &rest body)
    (and (eval expr) (progn-encapsulate body)))


>> The fact that such a macro call embedded in another form building form
>> that processes it properly doesn't mean that it is not bad style: it
>> has to do something special to the result of ifdef to make it work.
>> If you extract that ifdef call to run it at the repl, it just cannot
>> work.
>
> Yes.

-- 
__Pascal Bourguignon__


^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: Is it possible for a macro to expand to nothing?
  2009-11-24 10:45                   ` Alan Mackenzie
  2009-11-24 11:14                     ` Pascal J. Bourguignon
@ 2009-11-24 11:56                     ` Pascal J. Bourguignon
  1 sibling, 0 replies; 43+ messages in thread
From: Pascal J. Bourguignon @ 2009-11-24 11:56 UTC (permalink / raw
  To: help-gnu-emacs

Alan Mackenzie <acm@muc.de> writes:
>> The general contract of a macro is that it returns valid forms.
>
> Sorry, Pascal, you're just restating the same thing again, not answering
> my question.  Why should I accept this "general contract of a macro"?  I
> haven't signed it.  ;-)  Is there some respected Lisp guru who says this?
> What would this guru say about the macro which generates a
> font-lock-defaults structure?

Perhaps you could ask this question on news:comp.lang.lisp ?

-- 
__Pascal Bourguignon__


^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: Is it possible for a macro to expand to nothing?
  2009-11-24 11:14                     ` Pascal J. Bourguignon
@ 2009-11-24 16:39                       ` Alan Mackenzie
  2009-11-24 19:17                         ` Pascal J. Bourguignon
                                           ` (4 more replies)
  0 siblings, 5 replies; 43+ messages in thread
From: Alan Mackenzie @ 2009-11-24 16:39 UTC (permalink / raw
  To: help-gnu-emacs

Pascal J. Bourguignon <pjb@informatimago.com> wrote:
> Alan Mackenzie <acm@muc.de> writes:

>> Pascal J. Bourguignon <pjb@informatimago.com> wrote:
>>> Alan Mackenzie <acm@muc.de> writes:

>>>> Pascal J. Bourguignon <pjb@informatimago.com> wrote:
>>>>> "Drew Adams" <drew.adams@oracle.com> writes:

> Valid lisp code is the kind of lisp code that eval can process and
> return the result without signaling an error (it can signal errors
> internally, if they are caught).

OK.  It is quite valid for macros to generate portions of valid code, or
data upon which code can operate.

> My claim is that it is not a good style to write a macro that produces
> non valid lisp code, .....

So you have said, time after time, without producing any coherent
reasoning to back it up.  The following ....

> .... because lisp macros are designed to produce code that will be
> evaluated by the lisp eval,

, is a mere assertion which I am convinced is false.  It seems to be on a
par with saying "gotos are harmful".  Well, yes they are, sort of, but on
other occasions are useful indeed.  The same surely applies to lisp
macros which generate things not evalable.

> If you want to transform code for other processors, or random data, use
> functions.

Functions are not as usable as macros, or are more awkward and hence
error prone, or require excessive use of `eval-while-compile' and lots of
juggling with , ,@ ` and the like.

Your notion of the correct use of macros seems to be a religious idea
rather than one fully thought through.  You justify it with circular
reasoning.  Whilst using a macro to generate an evalable form may be the
most usual thing, there is no reason not to use it to produce other list
structure.



>>> But cc-langs.el only defines four macros and they all generate
>>> perfectly good lisp code.

>> Any macro, once debugged, generates "perfectly good" lisp code.  I
>> don't understand where this notion of "perfectly good" comes from.

> It means valid lisp code, see definition above.

Circular reasoning.

>>> Unfortunately, most of emacs lisp code is bad code.  Functions one
>>> kilometer long, chained with one or more others one kilometer long.
>>> Copy-and-pasted chunks instead of abstracting it away.  Etc.

>> I can't disagree with that, sadly.  However I think Emacs's code base
>> is better than a typical 25 yo application still under development (if
>> there is such a beast).

> Yes, the fact that it still runs, is still useful, and can still be
> maintained despite these bad parts is proof of it, that it's better
> than typical 25 yo or even a lot of much younger programs.


>>> The general contract of a macro is that it returns valid forms.

>> Sorry, Pascal, you're just restating the same thing again, not
>> answering my question.  Why should I accept this "general contract of
>> a macro"?  I haven't signed it.  ;-) Is there some respected Lisp guru
>> who says this?

> It comes directly from the definition of defmacro,

>    defmacro is a special form in `src/eval.c'.
>    (defmacro name arglist [docstring] [decl] body...)

>    Define name as a macro.
>    The actual definition looks like
>     (macro lambda arglist [docstring] [decl] body...).
>    When the macro is called, as in (name ARGS...),
>    the function (lambda arglist body...) is applied to
>    the list ARGS... as it appears in the expression,
>    and the result should be a form to be evaluated instead of the original.

Oh, come on!  That last sentence is a tutorial, motivating one, expressed
in the slightly loose, colloquial language of the hacker.  "a form to be
evaluated" is here shorthand for something like "some sort of atom or
list structure which fits into the slot where the invocation is housed"

>> What would this guru say about the macro which generates a
>> font-lock-defaults structure?

> If this structure cannot be passed to eval without signaling an error,
> then I would say that it is bad style to use a macro to generate such
> data.

OK.  So people who might have benefitted from a clever macro now have to
do things more laboriously and more erroneously.  Another example you
would call bad would be `define-minor-mode' which, in addition to
creating a top level command also creates a keymap, a syntax table, and
so on.  Would you propose eliminating `define-minor-mode' from Emacs?


>>> (defmacro ifdef (expr &rest body)
>>>   (and (eval expr) `(progn ,@body)))

>> That version of ifdef is ugly because it contains an obtrusive
>> `progn'.

> In a way here, progn is the dual of list.

> When you want to generate a list of data, you use list:

>  `(list  ,expr1 ,expr2 ... ,exprN)

> When you want to generate a list of code, you use progn:

>  `(progn ,form1 ,form2 ... ,formN)


> It is not obtrusive in any way, it only shows that we are generating
> code, not mere data.

It makes the generated code more difficult to read, because it has no
function, unless it has some specific function.


>> It seems this `progn' is there purely to satisfy
>> the (as yet unsubstantiated) injunction to return only "perfectly good"
>> lisp forms.

> Not 'purely'.  You could optimize it out when unnecessary with:

>  (defun progn-encapsulate (forms)
>    (if (= 1 (length forms)) 
>       (first forms)
>       (list* 'progn forms)))

, or I could just have the macro return (form1 form2 .... formn), ready
to be spliced into the caller.

-- 
Alan Mackenzie (Nuremberg, Germany).



^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: Is it possible for a macro to expand to nothing?
  2009-11-24 16:39                       ` Alan Mackenzie
@ 2009-11-24 19:17                         ` Pascal J. Bourguignon
  2009-11-25 14:13                         ` Jeff Clough
                                           ` (3 subsequent siblings)
  4 siblings, 0 replies; 43+ messages in thread
From: Pascal J. Bourguignon @ 2009-11-24 19:17 UTC (permalink / raw
  To: help-gnu-emacs

Alan Mackenzie <acm@muc.de> writes:

> Pascal J. Bourguignon <pjb@informatimago.com> wrote:
>> Alan Mackenzie <acm@muc.de> writes:
>>> What would this guru say about the macro which generates a
>>> font-lock-defaults structure?
>
>> If this structure cannot be passed to eval without signaling an error,
>> then I would say that it is bad style to use a macro to generate such
>> data.
>
> OK.  So people who might have benefitted from a clever macro now have to
> do things more laboriously and more erroneously.  

That's where you're wrong, using functions to generate data is
simplier and less erroneous than using macros to do the same.

> Another example you
> would call bad would be `define-minor-mode' which, in addition to
> creating a top level command also creates a keymap, a syntax table, and
> so on.  Would you propose eliminating `define-minor-mode' from Emacs?

define-minor-mode generates a valid lisp form. You can execute a
define-minor-mode macro call without getting an error.


>>>> (defmacro ifdef (expr &rest body)
>>>>   (and (eval expr) `(progn ,@body)))
>
>>> That version of ifdef is ugly because it contains an obtrusive
>>> `progn'.
>
>> In a way here, progn is the dual of list.
>
>> When you want to generate a list of data, you use list:
>
>>  `(list  ,expr1 ,expr2 ... ,exprN)
>
>> When you want to generate a list of code, you use progn:
>
>>  `(progn ,form1 ,form2 ... ,formN)
>
>
>> It is not obtrusive in any way, it only shows that we are generating
>> code, not mere data.
>
> It makes the generated code more difficult to read, because it has no
> function, unless it has some specific function.

Why do you use variable names from a natural language dictionnary?
Names have no function, you should use gensyms...


>>> It seems this `progn' is there purely to satisfy
>>> the (as yet unsubstantiated) injunction to return only "perfectly good"
>>> lisp forms.
>
>> Not 'purely'.  You could optimize it out when unnecessary with:
>
>>  (defun progn-encapsulate (forms)
>>    (if (= 1 (length forms)) 
>>       (first forms)
>>       (list* 'progn forms)))
>
> , or I could just have the macro return (form1 form2 .... formn), ready
> to be spliced into the caller.

No, because such a macro you couldn't use it at the REPL or in any
other  function.


-- 
__Pascal Bourguignon__


^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: Is it possible for a macro to expand to nothing?
  2009-11-24 16:39                       ` Alan Mackenzie
  2009-11-24 19:17                         ` Pascal J. Bourguignon
@ 2009-11-25 14:13                         ` Jeff Clough
       [not found]                         ` <mailman.11467.1259158369.2239.help-gnu-emacs@gnu.org>
                                           ` (2 subsequent siblings)
  4 siblings, 0 replies; 43+ messages in thread
From: Jeff Clough @ 2009-11-25 14:13 UTC (permalink / raw
  To: help-gnu-emacs

From: Alan Mackenzie <acm@muc.de>
Date: Tue, 24 Nov 2009 16:39:20 +0000 (UTC)

>> It comes directly from the definition of defmacro,
> 
>>    defmacro is a special form in `src/eval.c'.
>>    (defmacro name arglist [docstring] [decl] body...)
> 
>>    Define name as a macro.
>>    The actual definition looks like
>>     (macro lambda arglist [docstring] [decl] body...).
>>    When the macro is called, as in (name ARGS...),
>>    the function (lambda arglist body...) is applied to
>>    the list ARGS... as it appears in the expression,
>>    and the result should be a form to be evaluated instead of the original.
> 
> Oh, come on!  That last sentence is a tutorial, motivating one, expressed
> in the slightly loose, colloquial language of the hacker.  "a form to be
> evaluated" is here shorthand for something like "some sort of atom or
> list structure which fits into the slot where the invocation is housed"

This is incorrect.  The term "form" has a very specific definition in
Lisp.  It is a sexp that can be evaluated.  While I'm new to Lisp, I
have been knee deep in books and documents for the last couple of
weeks and everything (including the GNU Emacs Lisp Manual) presents
macros as a way to generate *forms*, not just sexps.

If you have a macro that expands to (1 2 3), it's not going to break
the world, but that macro isn't doing what every hacker is going to
expect.  I'd call that a style problem.

If, for some reason, you absolutely have to use a macro to generate
something like that above, at least have it expand to (list 1 2 3),
that way the macro can still be evaluated and no one gets shafted.
You get the behavior you want and the macro is still expanding to a
valid form.

Jeff





^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: Is it possible for a macro to expand to nothing?
       [not found]                         ` <mailman.11467.1259158369.2239.help-gnu-emacs@gnu.org>
@ 2009-11-26  6:53                           ` Alan Mackenzie
  2009-11-26 11:11                             ` Pascal J. Bourguignon
  0 siblings, 1 reply; 43+ messages in thread
From: Alan Mackenzie @ 2009-11-26  6:53 UTC (permalink / raw
  To: help-gnu-emacs

Jeff Clough <jeff@chaosphere.com> wrote:
> From: Alan Mackenzie <acm@muc.de>
> Date: Tue, 24 Nov 2009 16:39:20 +0000 (UTC)

>>> It comes directly from the definition of defmacro,

>>>    defmacro is a special form in `src/eval.c'.
>>>    (defmacro name arglist [docstring] [decl] body...)

>>>    Define name as a macro.  The actual definition looks like
>>>     (macro lambda arglist [docstring] [decl] body...).
>>>    When the macro is called, as in (name ARGS...), the function
>>>    (lambda arglist body...) is applied to the list ARGS... as it
>>>    appears in the expression, and the result should be a form to be
>>>    evaluated instead of the original.

>> Oh, come on!  That last sentence is a tutorial, motivating one,
>> expressed in the slightly loose, colloquial language of the hacker.
>> "a form to be evaluated" is here shorthand for something like "some
>> sort of atom or list structure which fits into the slot where the
>> invocation is housed"

> This is incorrect.  The term "form" has a very specific definition in
> Lisp.  It is a sexp that can be evaluated.  While I'm new to Lisp, I
> have been knee deep in books and documents for the last couple of weeks
> and everything (including the GNU Emacs Lisp Manual) presents macros as
> a way to generate *forms*, not just sexps.

You've missed my point.  The guy who wrote that definition of macro was,
in using the word "form", being somewhat, er, informal.  It was just
easier and more concise to say "form" than "form or (sometimes) other
appropriate list structure".

> If you have a macro that expands to (1 2 3), it's not going to break
> the world, but that macro isn't doing what every hacker is going to
> expect.  I'd call that a style problem.

Just like somebody occasionally using a goto in C.  Pascal was unable to
identify any specific problem a non-form macro expansion causes.

> If, for some reason, you absolutely have to use a macro to generate
> something like that above, at least have it expand to (list 1 2 3),
> that way the macro can still be evaluated and no one gets shafted.

And waste run time evaluating that list every time the defun runs?

> You get the behavior you want and the macro is still expanding to a
> valid form.

Nobody has yet given a valid reason why I should care about a macro
expansion being a "valid form" when the invoker is not going to evaluate
it.  cc-langs.el is chock full of such "invalid forms", yet they make the
maintenance of 7 complicated language modes tractable.

> Jeff

-- 
Alan Mackenzie (Nuremberg, Germany).



^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: Is it possible for a macro to expand to nothing?
  2009-11-26  6:53                           ` Alan Mackenzie
@ 2009-11-26 11:11                             ` Pascal J. Bourguignon
  2009-11-26 11:52                               ` Lennart Borgman
       [not found]                               ` <mailman.11564.1259236392.2239.help-gnu-emacs@gnu.org>
  0 siblings, 2 replies; 43+ messages in thread
From: Pascal J. Bourguignon @ 2009-11-26 11:11 UTC (permalink / raw
  To: help-gnu-emacs

Alan Mackenzie <acm@muc.de> writes:

> Jeff Clough <jeff@chaosphere.com> wrote:
>> From: Alan Mackenzie <acm@muc.de>
>> Date: Tue, 24 Nov 2009 16:39:20 +0000 (UTC)
>
>>>> It comes directly from the definition of defmacro,
>
>>>>    defmacro is a special form in `src/eval.c'.
>>>>    (defmacro name arglist [docstring] [decl] body...)
>
>>>>    Define name as a macro.  The actual definition looks like
>>>>     (macro lambda arglist [docstring] [decl] body...).
>>>>    When the macro is called, as in (name ARGS...), the function
>>>>    (lambda arglist body...) is applied to the list ARGS... as it
>>>>    appears in the expression, and the result should be a form to be
>>>>    evaluated instead of the original.
>
>>> Oh, come on!  That last sentence is a tutorial, motivating one,
>>> expressed in the slightly loose, colloquial language of the hacker.
>>> "a form to be evaluated" is here shorthand for something like "some
>>> sort of atom or list structure which fits into the slot where the
>>> invocation is housed"
>
>> This is incorrect.  The term "form" has a very specific definition in
>> Lisp.  It is a sexp that can be evaluated.  While I'm new to Lisp, I
>> have been knee deep in books and documents for the last couple of weeks
>> and everything (including the GNU Emacs Lisp Manual) presents macros as
>> a way to generate *forms*, not just sexps.
>
> You've missed my point.  The guy who wrote that definition of macro was,
> in using the word "form", being somewhat, er, informal.  It was just
> easier and more concise to say "form" than "form or (sometimes) other
> appropriate list structure".

He was informal only as much as the "emacs lisp reference manual"
doesn't contain a glossary entry for "form".  The reason why is that
because at the time emacs was invented, it was a well known technical
term established for 30 years meaning "an executable sexp".

Only a few years later did Common Lisp get formalized with a
normalizing glossary, where you can find the formal definition for
form which I cited.  Notice that it is justified to retrofit most
definitions of the Common Lisp glossary to the older lisps, since
Common Lisp is after all not much more than the GCD of the lisps that
existed at the time.



>> If you have a macro that expands to (1 2 3), it's not going to break
>> the world, but that macro isn't doing what every hacker is going to
>> expect.  I'd call that a style problem.
>
> Just like somebody occasionally using a goto in C.  Pascal was unable to
> identify any specific problem a non-form macro expansion causes.

I cited several times the reason why it's bad: because the macro form
cannot be used stand alone without signaling an error.  Jeff says the
same.  You could ask on comp.lang.lisp where I'd bet you'd get even
more gurus answering.  (Real lisp gurus intervene sometimes on cll).


>> If, for some reason, you absolutely have to use a macro to generate
>> something like that above, at least have it expand to (list 1 2 3),
>> that way the macro can still be evaluated and no one gets shafted.
>
> And waste run time evaluating that list every time the defun runs?

That depends on what you're doing.  But indeed, by advice is to use a
_function_ to return (1 2 3) and avoid rebuilding the list several
time.


>> You get the behavior you want and the macro is still expanding to a
>> valid form.
>
> Nobody has yet given a valid reason why I should care about a macro
> expansion being a "valid form" when the invoker is not going to evaluate
> it.  cc-langs.el is chock full of such "invalid forms", yet they make the
> maintenance of 7 complicated language modes tractable.

It is a _style_ reason.  A question of good taste.   The same reason
why you don't poop in your living room.   It would be bad style.


To make an analogy, there is a room where you can defecate, there's a
room where you watch TV.  Technically, there's no reason why you
shouldn't be able to defecate in your living room, but for style
reasons (and because you don't have to paper over it later), it's
better if you keep defecating in your water closed room.


-- 
__Pascal Bourguignon__


^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: Is it possible for a macro to expand to nothing?
  2009-11-26 11:11                             ` Pascal J. Bourguignon
@ 2009-11-26 11:52                               ` Lennart Borgman
       [not found]                               ` <mailman.11564.1259236392.2239.help-gnu-emacs@gnu.org>
  1 sibling, 0 replies; 43+ messages in thread
From: Lennart Borgman @ 2009-11-26 11:52 UTC (permalink / raw
  To: Pascal J. Bourguignon; +Cc: help-gnu-emacs

On Thu, Nov 26, 2009 at 12:11 PM, Pascal J. Bourguignon
<pjb@informatimago.com> wrote:
>
> It is a _style_ reason.  A question of good taste.   The same reason
> why you don't poop in your living room.   It would be bad style.


Now it is much easier to understand. I had the impression you had a
technical reason.




^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: Is it possible for a macro to expand to nothing?
       [not found]                               ` <mailman.11564.1259236392.2239.help-gnu-emacs@gnu.org>
@ 2009-11-26 12:16                                 ` Pascal J. Bourguignon
  2009-11-26 12:43                                   ` Lennart Borgman
  0 siblings, 1 reply; 43+ messages in thread
From: Pascal J. Bourguignon @ 2009-11-26 12:16 UTC (permalink / raw
  To: help-gnu-emacs

Lennart Borgman <lennart.borgman@gmail.com> writes:

> On Thu, Nov 26, 2009 at 12:11 PM, Pascal J. Bourguignon
> <pjb@informatimago.com> wrote:
>>
>> It is a _style_ reason.  A question of good taste.   The same reason
>> why you don't poop in your living room.   It would be bad style.
>
>
> Now it is much easier to understand. I had the impression you had a
> technical reason.

But stylistic reasons ARE technical reasons.  They're even very strong
technical reasons.

It's all bits, so in the end it doesn't matter what you do, does it?

However your programs will still be better if you respect the
abstractions and expectations required by the human programmer minds
to understand them and debug them.

Read for example:
http://smuglispweeny.blogspot.com/2008/07/aa-bb-cc-and-dd.html

-- 
__Pascal Bourguignon__


^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: Is it possible for a macro to expand to nothing?
  2009-11-26 12:16                                 ` Pascal J. Bourguignon
@ 2009-11-26 12:43                                   ` Lennart Borgman
  0 siblings, 0 replies; 43+ messages in thread
From: Lennart Borgman @ 2009-11-26 12:43 UTC (permalink / raw
  To: Pascal J. Bourguignon; +Cc: help-gnu-emacs

On Thu, Nov 26, 2009 at 1:16 PM, Pascal J. Bourguignon
<pjb@informatimago.com> wrote:
>
> But stylistic reasons ARE technical reasons.  They're even very strong
> technical reasons.


They can be, but they are not necessarily that. You must give an
argument for the style.




^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: Is it possible for a macro to expand to nothing?
  2009-11-24 16:39                       ` Alan Mackenzie
                                           ` (2 preceding siblings ...)
       [not found]                         ` <mailman.11467.1259158369.2239.help-gnu-emacs@gnu.org>
@ 2009-11-27  8:32                         ` Kevin Rodgers
       [not found]                         ` <mailman.11626.1259310779.2239.help-gnu-emacs@gnu.org>
  4 siblings, 0 replies; 43+ messages in thread
From: Kevin Rodgers @ 2009-11-27  8:32 UTC (permalink / raw
  To: help-gnu-emacs

Alan Mackenzie wrote:

> Your notion of the correct use of macros seems to be a religious idea
> rather than one fully thought through.  You justify it with circular
> reasoning.  Whilst using a macro to generate an evalable form may be the
> most usual thing, there is no reason not to use it to produce other list
> structure.

Except that such macros can only be executed in a particular context i.e.
they depend on something that cannot be expressed via their argument list.
At best that is poor style, and at worst it is poor engineering.

-- 
Kevin Rodgers
Denver, Colorado, USA





^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: Is it possible for a macro to expand to nothing?
       [not found]                         ` <mailman.11626.1259310779.2239.help-gnu-emacs@gnu.org>
@ 2009-11-27 13:15                           ` Alan Mackenzie
  2009-11-27 13:52                             ` Pascal J. Bourguignon
  2009-11-27 23:17                             ` Tim X
  0 siblings, 2 replies; 43+ messages in thread
From: Alan Mackenzie @ 2009-11-27 13:15 UTC (permalink / raw
  To: help-gnu-emacs

Kevin Rodgers <kevin.d.rodgers@gmail.com> wrote:
> Alan Mackenzie wrote:

>> Your notion of the correct use of macros seems to be a religious idea
>> rather than one fully thought through.  You justify it with circular
>> reasoning.  Whilst using a macro to generate an evalable form may be
>> the most usual thing, there is no reason not to use it to produce
>> other list structure.

> Except that such macros can only be executed in a particular context
> i.e.  they depend on something that cannot be expressed via their
> argument list.

Yes, many lisp structures can only be "executed" in particular contexts,
`,@' for example, yet nobody slags them off for that.


> At best that is poor style, and at worst it is poor engineering.

That is so supercilious - you haven't even given an example of this
phenomenom, discussing why it is poor style or poor engineering.  There's
just this vague insinuation that you know better.

I will give an example, namely `c-lang-defconst' from cc-defs.el.  Are
you going to assert that it is poor style, or even poor engineering,
simply because it generates an internal data structure rather than an
excutable form?  If so, then it's up to you to say how it could have been
done better, preferably submitting a patch.

-- 
Alan Mackenzie (Nuremberg, Germany).



^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: Is it possible for a macro to expand to nothing?
  2009-11-27 13:15                           ` Alan Mackenzie
@ 2009-11-27 13:52                             ` Pascal J. Bourguignon
  2009-11-27 16:57                               ` Alan Mackenzie
  2009-11-27 17:19                               ` Helmut Eller
  2009-11-27 23:17                             ` Tim X
  1 sibling, 2 replies; 43+ messages in thread
From: Pascal J. Bourguignon @ 2009-11-27 13:52 UTC (permalink / raw
  To: help-gnu-emacs

Alan Mackenzie <acm@muc.de> writes:

> Kevin Rodgers <kevin.d.rodgers@gmail.com> wrote:
>> Alan Mackenzie wrote:
>
>>> Your notion of the correct use of macros seems to be a religious idea
>>> rather than one fully thought through.  You justify it with circular
>>> reasoning.  Whilst using a macro to generate an evalable form may be
>>> the most usual thing, there is no reason not to use it to produce
>>> other list structure.
>
>> Except that such macros can only be executed in a particular context
>> i.e.  they depend on something that cannot be expressed via their
>> argument list.
>
> Yes, many lisp structures can only be "executed" in particular contexts,
> `,@' for example, yet nobody slags them off for that.

This is different.  Why can't you see it?

,@ cannot be put outside of a ` context, never ever.

When you define a macro  (defmacro  m ...)
then (m ...) can be put in any form context, always.

Oops! Not when you write a macro that returns not a form.  You've made
an exception, and therefore a lot of complexity for the reader of your
code, and a lot of time lost for the debugger of your code.

Now instead of being able to use a macro at any place a form is
acceptable, we have to go read the source of the macro, and understand
whether it returns a form or data, and if it's the later, we have to
understand how to wrap it in some boilerplate, which was by the way
why macros where invented for in the first place, to avoid
boilerplate!!!  How silly!



>> At best that is poor style, and at worst it is poor engineering.
>
> That is so supercilious - you haven't even given an example of this
> phenomenom, discussing why it is poor style or poor engineering.  There's
> just this vague insinuation that you know better.

Yes, it seems that we have to spell it in all details.


> I will give an example, namely `c-lang-defconst' from cc-defs.el.  Are
> you going to assert that it is poor style, or even poor engineering,
> simply because it generates an internal data structure rather than an
> excutable form?  

You are plain wrong.  c-lang-defconst, as any other macro, generates
only executable lisp code:

(c-lang-defconst test t nil c "abc")
--> test

(macroexpand '(c-lang-defconst test t nil c "abc"))
--> (progn (c-define-lang-constant (quote test) (quote (((c-mode) . "abc") (t))) (quote (\83))))



> If so, then it's up to you to say how it could have been
> done better, preferably submitting a patch.

There's no need it already returns lisp CODE, as it should.

-- 
__Pascal Bourguignon__


^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: Is it possible for a macro to expand to nothing?
  2009-11-27 13:52                             ` Pascal J. Bourguignon
@ 2009-11-27 16:57                               ` Alan Mackenzie
  2009-11-27 17:09                                 ` Pascal J. Bourguignon
  2009-11-27 17:19                               ` Helmut Eller
  1 sibling, 1 reply; 43+ messages in thread
From: Alan Mackenzie @ 2009-11-27 16:57 UTC (permalink / raw
  To: help-gnu-emacs

Pascal J. Bourguignon <pjb@informatimago.com> wrote:
> Alan Mackenzie <acm@muc.de> writes:

>> Kevin Rodgers <kevin.d.rodgers@gmail.com> wrote:
>>> Alan Mackenzie wrote:

>>>> Your notion of the correct use of macros seems to be a religious idea
>>>> rather than one fully thought through.  You justify it with circular
>>>> reasoning.  Whilst using a macro to generate an evalable form may be
>>>> the most usual thing, there is no reason not to use it to produce
>>>> other list structure.

>>> Except that such macros can only be executed in a particular context
>>> i.e.  they depend on something that cannot be expressed via their
>>> argument list.

>> Yes, many lisp structures can only be "executed" in particular contexts,
>> `,@' for example, yet nobody slags them off for that.

> This is different.  Why can't you see it?

I do see it.  I'm glad we both do - there are things which _are_
different.

> ,@ cannot be put outside of a ` context, never ever.

Yes.  It is a thing which can only be "executed" in a particular context.
We live with this.

> When you define a macro (defmacro m ...) then (m ...) can be put in any
> form context, always.

No.  When _you_ define a macro that might well be the case, but with me
there are no guarantees.  I might want a macro to generate an arm of a
cond form, for example.  Unlikely, but possible.

> Oops! Not when you write a macro that returns not a form.  You've made
> an exception, and therefore a lot of complexity for the reader of your
> code, and a lot of time lost for the debugger of your code.

Right.  We now get down to weighing up the difficulties a non-form macro
may cause to its readers compared with the simplicity in the manner of
expression which it would allow.

> Now instead of being able to use a macro at any place a form is
> acceptable, we have to go read the source of the macro, and understand
> whether it returns a form or data, and if it's the later, we have to
> understand how to wrap it in some boilerplate, which was by the way
> why macros where invented for in the first place, to avoid
> boilerplate!!!  How silly!

No, not silly - it all depends.  In the example which sparked off this
intelligent discussion, avoiding non-conformity required inserting an
artificial `progn'.  It's a matter of judgement which is the more
difficult to read and understand.



>>> At best that is poor style, and at worst it is poor engineering.

>> That is so supercilious - you haven't even given an example of this
>> phenomenom, discussing why it is poor style or poor engineering.  There's
>> just this vague insinuation that you know better.

> Yes, it seems that we have to spell it in all details.

Yes, indeed.  Or at least, in some considerable detail.

>> I will give an example, namely `c-lang-defconst' from cc-defs.el.  Are
>> you going to assert that it is poor style, or even poor engineering,
>> simply because it generates an internal data structure rather than an
>> excutable form?  

> You are plain wrong.  c-lang-defconst, as any other macro, generates
> only executable lisp code:

Yes, I was wrong.  Sorry about that.  I'm beginning to see what you're
getting at.

> (c-lang-defconst test t nil c "abc")
> --> test

> (macroexpand '(c-lang-defconst test t nil c "abc"))
> --> (progn (c-define-lang-constant (quote test) (quote (((c-mode) . "abc") (t))) (quote (\83))))

I still don't see the _reason_ for macros always to return forms.  I
think you're saying that anything else is so unusual that it would create
problems for somebody reading or debugging it.  Do you have an example of
somewhere where a macro expanding to a non-form has lead to difficulty?
I can't imagine anybody having difficulty understanding code like this:

(cond
 (try-incoming-call event)  ; expands to a full cond arm
 (try-incoming-data-call event)
 (try-battery-low-notification event)
 (try-keyboard-press event)
 ....
 )

, where all these event handler macros are defined centrally just once
(and the comment is actually present in the source).

I'll quite happily use a goto in C code if it makes the code easier to
read and understand, though I've only done this 3 or 4 times in my entire
career.  Similarly, I'd use a non-form macro if this were better.
Usually it wouldn't be.

-- 
Alan Mackenzie (Nuremberg, Germany).


^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: Is it possible for a macro to expand to nothing?
  2009-11-27 16:57                               ` Alan Mackenzie
@ 2009-11-27 17:09                                 ` Pascal J. Bourguignon
  0 siblings, 0 replies; 43+ messages in thread
From: Pascal J. Bourguignon @ 2009-11-27 17:09 UTC (permalink / raw
  To: help-gnu-emacs

Alan Mackenzie <acm@muc.de> writes:

> Pascal J. Bourguignon <pjb@informatimago.com> wrote:
>> When you define a macro (defmacro m ...) then (m ...) can be put in any
>> form context, always.
>
> No.  When _you_ define a macro that might well be the case, but with me
> there are no guarantees.  


Which would lead me to label you a bad lisp programmer.


> I might want a macro to generate an arm of a
> cond form, for example.  Unlikely, but possible.

Just say No.  Use a function.



>> Oops! Not when you write a macro that returns not a form.  You've made
>> an exception, and therefore a lot of complexity for the reader of your
>> code, and a lot of time lost for the debugger of your code.
>
> Right.  We now get down to weighing up the difficulties a non-form macro
> may cause to its readers compared with the simplicity in the manner of
> expression which it would allow.

That's silly!   It is much simplier to use and to write a function
than a macro here!



>> Now instead of being able to use a macro at any place a form is
>> acceptable, we have to go read the source of the macro, and understand
>> whether it returns a form or data, and if it's the later, we have to
>> understand how to wrap it in some boilerplate, which was by the way
>> why macros where invented for in the first place, to avoid
>> boilerplate!!!  How silly!
>
> No, not silly - it all depends.  In the example which sparked off this
> intelligent discussion, avoiding non-conformity required inserting an
> artificial `progn'.  

Not always, as I showed later.  It's simplier to put progn always,
(works with 0, 1 or n forms), but you can special case.


> It's a matter of judgement which is the more
> difficult to read and understand.

Again, if you don't believe me, you could try to ask this question on
cll and see what happens.  There seems to be more lisp hackers and
guru on cll.  



>>> I will give an example, namely `c-lang-defconst' from cc-defs.el.  Are
>>> you going to assert that it is poor style, or even poor engineering,
>>> simply because it generates an internal data structure rather than an
>>> excutable form?  
>
>> You are plain wrong.  c-lang-defconst, as any other macro, generates
>> only executable lisp code:
>
> Yes, I was wrong.  Sorry about that.  I'm beginning to see what you're
> getting at.
>
>> (c-lang-defconst test t nil c "abc")
>> --> test
>
>> (macroexpand '(c-lang-defconst test t nil c "abc"))
>> --> (progn (c-define-lang-constant (quote test) (quote (((c-mode) . "abc") (t))) (quote (\83))))
>
> I still don't see the _reason_ for macros always to return forms.  

Because that's what they're defined to do. This is the fundamental
contract of a macro.  When you don't know anything about a macro, you
know that it will return code.


> I think you're saying that anything else is so unusual that it would create
> problems for somebody reading or debugging it.  Do you have an example of
> somewhere where a macro expanding to a non-form has lead to difficulty?
> I can't imagine anybody having difficulty understanding code like this:
>
> (cond
>  (try-incoming-call event)  ; expands to a full cond arm
>  (try-incoming-data-call event)
>  (try-battery-low-notification event)
>  (try-keyboard-press event)
>  ....
>  )
>
> , where all these event handler macros are defined centrally just once
> (and the comment is actually present in the source).

To begin with, the above cond form doesn't do what you think.  In the
best case it will signal a void-variable error, in the worst cases it
will return the value of event.



> I'll quite happily use a goto in C code if it makes the code easier to
> read and understand, though I've only done this 3 or 4 times in my entire
> career.  Similarly, I'd use a non-form macro if this were better.

Why stop at non-form macros?  Functions are perfect for that task!


> Usually it wouldn't be.


-- 
__Pascal Bourguignon__


^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: Is it possible for a macro to expand to nothing?
  2009-11-27 13:52                             ` Pascal J. Bourguignon
  2009-11-27 16:57                               ` Alan Mackenzie
@ 2009-11-27 17:19                               ` Helmut Eller
  2009-11-27 17:45                                 ` Pascal J. Bourguignon
  1 sibling, 1 reply; 43+ messages in thread
From: Helmut Eller @ 2009-11-27 17:19 UTC (permalink / raw
  To: help-gnu-emacs

* Pascal J. Bourguignon [2009-11-27 14:52+0100] writes:

> ,@ cannot be put outside of a ` context, never ever.

That's not true.  ,@ outside of backquote is just an ordinary symbol:

(defun ,@ () "it works")
(defun , () "this works too")
(message "See, how %s.  And %s." (,@) (,))

Helmut


^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: Is it possible for a macro to expand to nothing?
  2009-11-27 17:19                               ` Helmut Eller
@ 2009-11-27 17:45                                 ` Pascal J. Bourguignon
  0 siblings, 0 replies; 43+ messages in thread
From: Pascal J. Bourguignon @ 2009-11-27 17:45 UTC (permalink / raw
  To: help-gnu-emacs

Helmut Eller <eller.helmut@gmail.com> writes:

> * Pascal J. Bourguignon [2009-11-27 14:52+0100] writes:
>
>> ,@ cannot be put outside of a ` context, never ever.
>
> That's not true.  ,@ outside of backquote is just an ordinary symbol:
>
> (defun ,@ () "it works")
> (defun , () "this works too")
> (message "See, how %s.  And %s." (,@) (,))

Oops!   (I was right in Common Lisp, but emacs lisp is different here).

-- 
__Pascal Bourguignon__


^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: Is it possible for a macro to expand to nothing?
  2009-11-27 13:15                           ` Alan Mackenzie
  2009-11-27 13:52                             ` Pascal J. Bourguignon
@ 2009-11-27 23:17                             ` Tim X
  2009-11-28  0:06                               ` Pascal J. Bourguignon
  1 sibling, 1 reply; 43+ messages in thread
From: Tim X @ 2009-11-27 23:17 UTC (permalink / raw
  To: help-gnu-emacs

Alan Mackenzie <acm@muc.de> writes:

> Kevin Rodgers <kevin.d.rodgers@gmail.com> wrote:
>> Alan Mackenzie wrote:
>
>>> Your notion of the correct use of macros seems to be a religious idea
>>> rather than one fully thought through.  You justify it with circular
>>> reasoning.  Whilst using a macro to generate an evalable form may be
>>> the most usual thing, there is no reason not to use it to produce
>>> other list structure.
>
>> Except that such macros can only be executed in a particular context
>> i.e.  they depend on something that cannot be expressed via their
>> argument list.
>
> Yes, many lisp structures can only be "executed" in particular contexts,
> `,@' for example, yet nobody slags them off for that.
>
>
>> At best that is poor style, and at worst it is poor engineering.
>
> That is so supercilious - you haven't even given an example of this
> phenomenom, discussing why it is poor style or poor engineering.  There's
> just this vague insinuation that you know better.
>
> I will give an example, namely `c-lang-defconst' from cc-defs.el.  Are
> you going to assert that it is poor style, or even poor engineering,
> simply because it generates an internal data structure rather than an
> excutable form?  If so, then it's up to you to say how it could have been
> done better, preferably submitting a patch.

I have found this an interesting discussion. I'm not sure which side of
the fence I fall on. 

Pascal/s assertion this is not good style has considerable merit. In
general, I think most do expect the result from a macro to be a form
that can be evaluated. 

On the other hand, Alan's arguments also have merit. If a macro can be
useful in generating something other than a form that can be evaluated,
such as a data structure and can do so in a way that is cleaner/simpler
or just easier to understand than doing the same using functions, then
it would make sense. His examples from the C modes seem to be a case in
point. 

To some extent, I would suggest this is one of those situations where
its ok to break the 'rules' provided you understand what the rules are
and you make it explicit in your comments/documentation that this is an
exception to the more common usage. In other words, Pascal is correect
that generally, good style would dictate that a macro returns a form
that can be evaluated. At the same time, if there is a situation where
using a macro in a way that isn't totally in keeping with good style
will result in code that is easier to understand/maintain, then it is
reasonable to do so provided this is documented and made clear. to some
extent, this follows Alan's example regarding goto. While good style
suggests you should avoid goto, there are situations where using goto is
the clearest and most maintainable solution, especially if avoiding its
use makes you jump through a whole lot of hoops to simply avoid
something that  someone has said is bad style. 

The whole notion of what is and is not good style is all about making
your code easier to understand and maintain. Style should not be viewed
as a set of rules that can never be broken (or change for that
matter). If anything, style guidelines are simply that, guidelines on
how to write your code to make it easier to understand and
maintain. When first programming, its a good idea to follow style
guidelines quite religiously. However, once you understand why the
guidelines are there and you become more experienced, you should
understand the difference between good and bad code and know when you
can break the rules.  

There is also a certain amount of personal taste/style that needs to be
considered. I've seen code that follows all recommended style guidelines
that is still almost impossible to understand and I've seen code that
appears to break many style guidelines that is very clear and easy to
follow. What I've found to be far more important is consistency. When
working with someone elses code, you get a feel for their style and way
of programming. Provided they are consistent, this isn't too bad
regardless of their adherence to common style guidelines. The worst is
code that sometimes adheres to guidelines and sometimes does not. My
view is to try and follow the 'accepted' style guidelines for the
language you are working in and document situations where you thought it
necessary to do something different that is outside normal style
conventions.

Tim
 

-- 
tcross (at) rapttech dot com dot au


^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: Is it possible for a macro to expand to nothing?
  2009-11-27 23:17                             ` Tim X
@ 2009-11-28  0:06                               ` Pascal J. Bourguignon
  2009-11-28  8:29                                 ` Alan Mackenzie
  0 siblings, 1 reply; 43+ messages in thread
From: Pascal J. Bourguignon @ 2009-11-28  0:06 UTC (permalink / raw
  To: help-gnu-emacs

Tim X <timx@nospam.dev.null> writes:

> On the other hand, Alan's arguments also have merit. If a macro can be
> useful in generating something other than a form that can be evaluated,
> such as a data structure and can do so in a way that is cleaner/simpler
> or just easier to understand than doing the same using functions, then
> it would make sense. His examples from the C modes seem to be a case in
> point. 


Perhaps Alan's problem with functions comes from the confusion between
backquote and macros.  Since backquote (and , and ,@) are often used
in macros, some people believe they can be used only in macros, and
that they ARE what macros are.


Far from it!  I don't know any language more orthogonal than lisp.


Backquote can be used in a function to build a s-exp (including part
of a form) as it can be used anywhere.

Therefore it is really not easier to use macros to generate parts of a
form than function.



You should never write or use a macro to generate data.  To generate
data, always use functions:

(defun generate-cond-clause (var predicate body)
   `((,predicate ,var) ,@body))


So then you can write a macro using this functio:

(defmacro pcase (expr &rest clauses)
  (let ((var (gensym)))
    `(let ((,var ,expr))
        (cond
          ,@(mapcar (lambda (clause)
                       (generate-cond-clause var (first clause) (rest clause)))
                    clauses)))))

(macroexpand '
 (pcase 42
   (oddp     (print 'odd)      1)
   (zerop    (print 'zero)     0)
   (integerp (print 'even)     2)
   (identity (print 'anything) 3)
   (null     (print 'null)     nil)))
-->
(let ((G62061 42))
   (cond ((oddp G62061) (print (quote odd)) 1)
         ((zerop G62061) (print (quote zero)) 0)
         ((integerp G62061) (print (quote even)) 2)
         ((identity G62061) (print (quote anything)) 3)
         ((null G62061) (print (quote null)) nil)))



If you wanted to use macros, in addition to the complexity of having
to use macroexpand to use it, you would have the difficulty of passing
the parameters, since a macro gets it's parameters from the source
form.  In the case of a function, you have the choice to quote or not
to quote the parameters, with macros they're always quoted for you.


-- 
__Pascal Bourguignon__


^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: Is it possible for a macro to expand to nothing?
  2009-11-28  0:06                               ` Pascal J. Bourguignon
@ 2009-11-28  8:29                                 ` Alan Mackenzie
  2009-11-28 10:25                                   ` Pascal J. Bourguignon
  0 siblings, 1 reply; 43+ messages in thread
From: Alan Mackenzie @ 2009-11-28  8:29 UTC (permalink / raw
  To: help-gnu-emacs

Pascal J. Bourguignon <pjb@informatimago.com> wrote:
> Tim X <timx@nospam.dev.null> writes:

>> On the other hand, Alan's arguments also have merit. If a macro can be
>> useful in generating something other than a form that can be
>> evaluated, such as a data structure and can do so in a way that is
>> cleaner/simpler or just easier to understand than doing the same using
>> functions, then it would make sense. His examples from the C modes
>> seem to be a case in point.


> Perhaps Alan's problem with functions comes from the confusion between
> backquote and macros.  Since backquote (and , and ,@) are often used in
> macros, some people believe they can be used only in macros, and that
> they ARE what macros are.

Er, do I actually have a problem with functions?  But no, I don't suffer
that particular confusion between backquotes and macros, and have indeed
used backquote when there hasn't been a macro within zeptoparsecs.

> Far from it!  I don't know any language more orthogonal than lisp.

Maybe not, but even lisp only gets to about 89 degrees.  It is missing an
operator which does the same as ,@ outside backquote.  This is one of the
lacks which makes it so difficult to write an equivalent of C's #if.

> Backquote can be used in a function to build a s-exp (including part of
> a form) as it can be used anywhere.

> Therefore it is really not easier to use macros to generate parts of a
> form than function.

It is if you need "side effects", like c-lang-defconst and friends do.

[ Stuff read and appreciated.  My brain's not up to it so early in the
morning].

> If you wanted to use macros, in addition to the complexity of having
> to use macroexpand to use it, you would have the difficulty of passing
> the parameters, since a macro gets it's parameters from the source
> form.  In the case of a function, you have the choice to quote or not
> to quote the parameters, with macros they're always quoted for you.

In the case of a function, you've GOT to quote, which can get very
tedious in some circumstances.  That's probably the reason that Martin
Stjernholm wrote c-lang-const etc. as macros.

-- 
Alan Mackenzie (Nuremberg, Germany).



^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: Is it possible for a macro to expand to nothing?
  2009-11-28  8:29                                 ` Alan Mackenzie
@ 2009-11-28 10:25                                   ` Pascal J. Bourguignon
  2009-11-28 12:57                                     ` Thierry Volpiatto
       [not found]                                     ` <mailman.11699.1259413441.2239.help-gnu-emacs@gnu.org>
  0 siblings, 2 replies; 43+ messages in thread
From: Pascal J. Bourguignon @ 2009-11-28 10:25 UTC (permalink / raw
  To: help-gnu-emacs

Alan Mackenzie <acm@muc.de> writes:

> Pascal J. Bourguignon <pjb@informatimago.com> wrote:
>> Tim X <timx@nospam.dev.null> writes:
>
>>> On the other hand, Alan's arguments also have merit. If a macro can be
>>> useful in generating something other than a form that can be
>>> evaluated, such as a data structure and can do so in a way that is
>>> cleaner/simpler or just easier to understand than doing the same using
>>> functions, then it would make sense. His examples from the C modes
>>> seem to be a case in point.
>
>
>> Perhaps Alan's problem with functions comes from the confusion between
>> backquote and macros.  Since backquote (and , and ,@) are often used in
>> macros, some people believe they can be used only in macros, and that
>> they ARE what macros are.
>
> Er, do I actually have a problem with functions?  But no, I don't suffer
> that particular confusion between backquotes and macros, and have indeed
> used backquote when there hasn't been a macro within zeptoparsecs.
>
>> Far from it!  I don't know any language more orthogonal than lisp.
>
> Maybe not, but even lisp only gets to about 89 degrees.  It is missing an
> operator which does the same as ,@ outside backquote.  This is one of the
> lacks which makes it so difficult to write an equivalent of C's #if.

Yes, emacs lisp is missing reader macros.  In Common Lisp there's #+,
#- and #., and reader macros may return 0 object.


>> Backquote can be used in a function to build a s-exp (including part of
>> a form) as it can be used anywhere.
>
>> Therefore it is really not easier to use macros to generate parts of a
>> form than function.
>
> It is if you need "side effects", like c-lang-defconst and friends do.

Well, I'm not sure about emacs, but in the case of Common Lisp, you
have to be careful with side effects in macros, because it is not
specified how many times, and when, macro functions are called.

I'd say that with emacs you at least have the same problem if you load
and/or eval the contents of a file and then you byte-compile it, the
macros may be executed twice.

So that's one more difficulty you have to cater to with macros, that
you don't have with functions.


> [ Stuff read and appreciated.  My brain's not up to it so early in the
> morning].
>
>> If you wanted to use macros, in addition to the complexity of having
>> to use macroexpand to use it, you would have the difficulty of passing
>> the parameters, since a macro gets it's parameters from the source
>> form.  In the case of a function, you have the choice to quote or not
>> to quote the parameters, with macros they're always quoted for you.
>
> In the case of a function, you've GOT to quote, which can get very
> tedious in some circumstances.  That's probably the reason that Martin
> Stjernholm wrote c-lang-const etc. as macros.

Read again my example, I hadn't to quote the arguments to the function
because they weren't the literal arguments, but variables containing
the arguments, because the function was called from another function
or macro (macro in this case) who got them as parameter.

If you had to forward arguments to a macro, it would be much more
complicated. Then you would have to use macroexpand.  

-- 
__Pascal Bourguignon__


^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: Is it possible for a macro to expand to nothing?
  2009-11-28 10:25                                   ` Pascal J. Bourguignon
@ 2009-11-28 12:57                                     ` Thierry Volpiatto
       [not found]                                     ` <mailman.11699.1259413441.2239.help-gnu-emacs@gnu.org>
  1 sibling, 0 replies; 43+ messages in thread
From: Thierry Volpiatto @ 2009-11-28 12:57 UTC (permalink / raw
  To: help-gnu-emacs

pjb@informatimago.com (Pascal J. Bourguignon) writes:

> Alan Mackenzie <acm@muc.de> writes:
>
>> Pascal J. Bourguignon <pjb@informatimago.com> wrote:
>>> Tim X <timx@nospam.dev.null> writes:
>>
>>>> On the other hand, Alan's arguments also have merit. If a macro can be
>>>> useful in generating something other than a form that can be
>>>> evaluated, such as a data structure and can do so in a way that is
>>>> cleaner/simpler or just easier to understand than doing the same using
>>>> functions, then it would make sense. His examples from the C modes
>>>> seem to be a case in point.
>>
>>
>>> Perhaps Alan's problem with functions comes from the confusion between
>>> backquote and macros.  Since backquote (and , and ,@) are often used in
>>> macros, some people believe they can be used only in macros, and that
>>> they ARE what macros are.
>>
>> Er, do I actually have a problem with functions?  But no, I don't suffer
>> that particular confusion between backquotes and macros, and have indeed
>> used backquote when there hasn't been a macro within zeptoparsecs.
>>
>>> Far from it!  I don't know any language more orthogonal than lisp.
>>
>> Maybe not, but even lisp only gets to about 89 degrees.  It is missing an
>> operator which does the same as ,@ outside backquote.  This is one of the
>> lacks which makes it so difficult to write an equivalent of C's #if.
>
> Yes, emacs lisp is missing reader macros.  In Common Lisp there's #+,
> #- and #., and reader macros may return 0 object.

A little note about #., it have emacs equivalent `eval-when-compile':

,----[ That is the CL version ]
|  -- Special Form: eval-when-compile forms...
|      The FORMS are evaluated at compile-time; at execution time, this
|      form acts like a quoted constant of the resulting value.  Used at
|      top-level, `eval-when-compile' is just like `eval-when (compile
|      eval)'.  In other contexts, `eval-when-compile' allows code to be
|      evaluated once at compile-time for efficiency or other reasons.
| 
|      This form is similar to the `#.' syntax of true Common Lisp.
`----

I don't know the #- and #+ macros, what are they for?

>
>>> Backquote can be used in a function to build a s-exp (including part of
>>> a form) as it can be used anywhere.
>>
>>> Therefore it is really not easier to use macros to generate parts of a
>>> form than function.
>>
>> It is if you need "side effects", like c-lang-defconst and friends do.
>
> Well, I'm not sure about emacs, but in the case of Common Lisp, you
> have to be careful with side effects in macros, because it is not
> specified how many times, and when, macro functions are called.
>
> I'd say that with emacs you at least have the same problem if you load
> and/or eval the contents of a file and then you byte-compile it, the
> macros may be executed twice.
>
> So that's one more difficulty you have to cater to with macros, that
> you don't have with functions.
>
>
>> [ Stuff read and appreciated.  My brain's not up to it so early in the
>> morning].
>>
>>> If you wanted to use macros, in addition to the complexity of having
>>> to use macroexpand to use it, you would have the difficulty of passing
>>> the parameters, since a macro gets it's parameters from the source
>>> form.  In the case of a function, you have the choice to quote or not
>>> to quote the parameters, with macros they're always quoted for you.
>>
>> In the case of a function, you've GOT to quote, which can get very
>> tedious in some circumstances.  That's probably the reason that Martin
>> Stjernholm wrote c-lang-const etc. as macros.
>
> Read again my example, I hadn't to quote the arguments to the function
> because they weren't the literal arguments, but variables containing
> the arguments, because the function was called from another function
> or macro (macro in this case) who got them as parameter.
>
> If you had to forward arguments to a macro, it would be much more
> complicated. Then you would have to use macroexpand.  

-- 
A + Thierry Volpiatto
Location: Saint-Cyr-Sur-Mer - France





^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: Is it possible for a macro to expand to nothing?
       [not found]                                     ` <mailman.11699.1259413441.2239.help-gnu-emacs@gnu.org>
@ 2009-11-29  0:54                                       ` Pascal J. Bourguignon
  0 siblings, 0 replies; 43+ messages in thread
From: Pascal J. Bourguignon @ 2009-11-29  0:54 UTC (permalink / raw
  To: help-gnu-emacs

Thierry Volpiatto <thierry.volpiatto@gmail.com> writes:

> pjb@informatimago.com (Pascal J. Bourguignon) writes:
>
>> Alan Mackenzie <acm@muc.de> writes:
>>
>>> Pascal J. Bourguignon <pjb@informatimago.com> wrote:
>>>> Tim X <timx@nospam.dev.null> writes:
>>>
>>>>> On the other hand, Alan's arguments also have merit. If a macro can be
>>>>> useful in generating something other than a form that can be
>>>>> evaluated, such as a data structure and can do so in a way that is
>>>>> cleaner/simpler or just easier to understand than doing the same using
>>>>> functions, then it would make sense. His examples from the C modes
>>>>> seem to be a case in point.
>>>
>>>
>>>> Perhaps Alan's problem with functions comes from the confusion between
>>>> backquote and macros.  Since backquote (and , and ,@) are often used in
>>>> macros, some people believe they can be used only in macros, and that
>>>> they ARE what macros are.
>>>
>>> Er, do I actually have a problem with functions?  But no, I don't suffer
>>> that particular confusion between backquotes and macros, and have indeed
>>> used backquote when there hasn't been a macro within zeptoparsecs.
>>>
>>>> Far from it!  I don't know any language more orthogonal than lisp.
>>>
>>> Maybe not, but even lisp only gets to about 89 degrees.  It is missing an
>>> operator which does the same as ,@ outside backquote.  This is one of the
>>> lacks which makes it so difficult to write an equivalent of C's #if.
>>
>> Yes, emacs lisp is missing reader macros.  In Common Lisp there's #+,
>> #- and #., and reader macros may return 0 object.
>
> A little note about #., it have emacs equivalent `eval-when-compile':

But #. is not eval when compile, it's eval when reading!
Compilation occurs much later after reading...

'#.(+ 1 2) --> 3

The result 3 is computed when reading the quote form.  
What is read is (quote 3):  

(read-from-string "'#.(+ 1 2)") --> (quote 3) ; 10



> I don't know the #- and #+ macros, what are they for?

   #+KEY THING

is equivalent to cpp:

    #ifdef KEY
    THING
    #endif

only it's not textual. #- <=> #ifndef


What is tested is the presence of the keyword :KEY in the *FEATURES* list.

(when (zerop (random 2)) (push :test *features*))
'(#+test present #-test absent) --> (present) or (absent)


-- 
__Pascal Bourguignon__


^ permalink raw reply	[flat|nested] 43+ messages in thread

end of thread, other threads:[~2009-11-29  0:54 UTC | newest]

Thread overview: 43+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-11-23 14:56 Is it possible for a macro to expand to nothing? Alan Mackenzie
2009-11-23 16:03 ` Drew Adams
     [not found] ` <mailman.11344.1258992201.2239.help-gnu-emacs@gnu.org>
2009-11-23 16:31   ` Alan Mackenzie
2009-11-23 17:29     ` Drew Adams
2009-11-23 18:33     ` Pascal J. Bourguignon
2009-11-23 18:51       ` Drew Adams
     [not found]       ` <mailman.11354.1259004470.2239.help-gnu-emacs@gnu.org>
2009-11-23 20:08         ` Pascal J. Bourguignon
2009-11-23 20:24           ` Alan Mackenzie
2009-11-23 22:09           ` Drew Adams
     [not found]           ` <mailman.11367.1259014174.2239.help-gnu-emacs@gnu.org>
2009-11-23 23:55             ` Pascal J. Bourguignon
2009-11-24  0:55               ` Alan Mackenzie
2009-11-24  9:42                 ` Pascal J. Bourguignon
2009-11-24 10:45                   ` Alan Mackenzie
2009-11-24 11:14                     ` Pascal J. Bourguignon
2009-11-24 16:39                       ` Alan Mackenzie
2009-11-24 19:17                         ` Pascal J. Bourguignon
2009-11-25 14:13                         ` Jeff Clough
     [not found]                         ` <mailman.11467.1259158369.2239.help-gnu-emacs@gnu.org>
2009-11-26  6:53                           ` Alan Mackenzie
2009-11-26 11:11                             ` Pascal J. Bourguignon
2009-11-26 11:52                               ` Lennart Borgman
     [not found]                               ` <mailman.11564.1259236392.2239.help-gnu-emacs@gnu.org>
2009-11-26 12:16                                 ` Pascal J. Bourguignon
2009-11-26 12:43                                   ` Lennart Borgman
2009-11-27  8:32                         ` Kevin Rodgers
     [not found]                         ` <mailman.11626.1259310779.2239.help-gnu-emacs@gnu.org>
2009-11-27 13:15                           ` Alan Mackenzie
2009-11-27 13:52                             ` Pascal J. Bourguignon
2009-11-27 16:57                               ` Alan Mackenzie
2009-11-27 17:09                                 ` Pascal J. Bourguignon
2009-11-27 17:19                               ` Helmut Eller
2009-11-27 17:45                                 ` Pascal J. Bourguignon
2009-11-27 23:17                             ` Tim X
2009-11-28  0:06                               ` Pascal J. Bourguignon
2009-11-28  8:29                                 ` Alan Mackenzie
2009-11-28 10:25                                   ` Pascal J. Bourguignon
2009-11-28 12:57                                     ` Thierry Volpiatto
     [not found]                                     ` <mailman.11699.1259413441.2239.help-gnu-emacs@gnu.org>
2009-11-29  0:54                                       ` Pascal J. Bourguignon
2009-11-24 11:56                     ` Pascal J. Bourguignon
     [not found]     ` <mailman.11352.1258997403.2239.help-gnu-emacs@gnu.org>
2009-11-23 18:42       ` Pascal J. Bourguignon
2009-11-23 20:12         ` Drew Adams
     [not found]         ` <mailman.11356.1259007263.2239.help-gnu-emacs@gnu.org>
2009-11-23 20:21           ` Pascal J. Bourguignon
2009-11-23 22:09             ` Drew Adams
     [not found]             ` <mailman.11368.1259014177.2239.help-gnu-emacs@gnu.org>
2009-11-24  0:03               ` Pascal J. Bourguignon
2009-11-23 20:09       ` Alan Mackenzie
2009-11-23 16:49 ` Jeff Clough

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.