From: Arend-Jan de Groote
Subject: Apply-macro?
Date: 
Message-ID: <3641EBDD.3C20@cs.uu.nl>
I really enjoy reading this group, and I'm glad I finally have a
question that's worth asking:

What I want is to call the macro 'or' with the elements of a list 'lst'.

If it were a function I'd just say (apply fn lst).
Is there a macro-equivalent to apply?

The solution I've thought of is
 (eval `(or ,@lst))
,but you taught me never to use eval. ;)

Why is there no 'apply-macro'?
I could write my own, but I have the feeling I'm missing something
simple.

Thanks,

Arend.

From: Kent M Pitman
Subject: Re: Apply-macro?
Date: 
Message-ID: <sfwyappub6f.fsf@world.std.com>
Arend-Jan de Groote <·····@cs.uu.nl> writes:

> I really enjoy reading this group, and I'm glad I finally have a
> question that's worth asking:
> 
> What I want is to call the macro 'or' with the elements of a list 'lst'.
> 
> If it were a function I'd just say (apply fn lst).
> Is there a macro-equivalent to apply?
> 
> The solution I've thought of is
>  (eval `(or ,@lst))
> ,but you taught me never to use eval. ;)
> 

(some #'identity lst)  ;though "list" is a better variable name

> Why is there no 'apply-macro'?

because it is conceptually more ill-formed than it may look
interactively.  macros are really to be done to a raw form at
"pre-processing time" which means at the time something is to be
compiled.  functions are to be applied to objects (the result of
evaluating something) at runtime.

also, in principle, a macro has access to the entire form (for
possible indexing or side-effect), not just the arguments.  in the
case of apply, there is no object whose identity is "the entire
form"--there are two objects, the symbol naming the macro and the list
of arguments (which may be the result of an evaluation, so may be
fresh and not something with a pre-existing identity).  so the fit
is kind of weird.  it may or may not make sense why this matters,
and to some degree it does matter less in modern systems; i've never
quite rationalized that in my mind.  but in older lisps, it used to
be very common to do things like
 (defun first macro (form) (rplaca form 'car))
this actually changed the source form, so if you were to apply
this (which you couldn't, but you can use your imagination), there
would be no real cons to rplaca.  you could imagine APPLY doing
a call to CONS to create that cons, but then you'd get screwed
if the macro definition side-effected BOTH the freshly consed
toplevel cell and some other cell on the backbone because presumably
these both need to be changed in lockstep.  consider:
 (defmacro list-of-one-above (&whole form thing)
   (check-type thing integer)
   (setf (car form) 'list)
   (setf (cadr form) (1+ thing))
   form)
then consider
 (macroexpand (setq x '(list-of-one-above 2)))
 => (LIST 3)
 x
 => (LIST 3)
but if you had some weird APPLY-MACRO thing, it would presumably
have to cons the two parts and do eval, so:
 (setq macro-name 'list-of-one-above)
 (setq macro-args '(2))
 (macroexpand '(cons macro-name macro-args))
 => (LIST 3)
 macro-name => LIST-OF-ONE-ABOVE
 macro-args => (3)

UH,OH.  I hope you can see why this is a problem.  object identity is
important in case of side-effects.  and macros used to do that.  they
also used to do "memoization" (the term we used to use for what is now
probably called just "caching") of macro expansions for faster use of
interpreted code (something most implementations don't fuss over any
more because most people don't run large parts of an application
interpreted).

> I could write my own, but I have the feeling I'm missing something
> simple.

Well, the simple thing you're overlooking is SOME and EVERY,
which are effectively "applicable OR" and "applicable AND" if you
pass #'identity as the test.

But as to why there are no applicable macros--well, that's hardly
simple as you've seen above.  For more about the history of this,
see my recently-webbed paper "Special Forms in Lisp" from the
1980 lisp conference.  It's old and dusty, and you have to take it
in its historical context, but it has a lot of things to say to a
modern audience.  And I've tried to annotate it to make it more 
readable by people who don't know Maclisp.
 http://world.std.com/~pitman/Papers/Special-Forms.html

Good luck.
 --Kent
From: Rainer Joswig
Subject: Re: Apply-macro?
Date: 
Message-ID: <joswig-0511982203400001@194.163.195.67>
In article <·············@cs.uu.nl>, Arend-Jan de Groote <·····@cs.uu.nl> wrote:

> I really enjoy reading this group, and I'm glad I finally have a
> question that's worth asking:
> 
> What I want is to call the macro 'or' with the elements of a list 'lst'.
> 
> If it were a function I'd just say (apply fn lst).
> Is there a macro-equivalent to apply?

No.

> The solution I've thought of is
>  (eval `(or ,@lst))
> ,but you taught me never to use eval. ;)
> 
> Why is there no 'apply-macro'?
> I could write my own, but I have the feeling I'm missing something
> simple.
> 
> Thanks,
> 
> Arend.

(reduce #'(lambda (a b)
            (or a b))
        '(nil t nil)
        :initial-value nil)

or 

(some #'identity '(nil t nil))

-- 
http://www.lavielle.com/~joswig
From: Johannes Beck
Subject: Re: Apply-macro?
Date: 
Message-ID: <364CAEC1.CC837684@informatik.uni-wuerzburg.de>
Rainer Joswig schrieb:
> 
> In article <·············@cs.uu.nl>, Arend-Jan de Groote <·····@cs.uu.nl> wrote:
> 
> > I really enjoy reading this group, and I'm glad I finally have a
> > question that's worth asking:
> >
> > What I want is to call the macro 'or' with the elements of a list 'lst'.
> >
> > If it were a function I'd just say (apply fn lst).
> > Is there a macro-equivalent to apply?
> 
> No.

Allegro (at least ACL 3.0 & 5.0 on windows) has a
mapply and mfuncall which are the same as apply and funcall
only for macros. Maybe you ask Franz for the implementation
of these...
 
> > The solution I've thought of is
> > ...
> > simple.

Johannes Beck


--
Johannes Beck   ····@informatik.uni-wuerzburg.de
                http://www-info6.informatik.uni-wuerzburg.de/~beck/
                Am Hoelzlein 35, 97076 Wuerzburg       
                Tel.: 0931/312198, 0931/275841

PGP Public-Key available by 
                ·············@www-info6.informatik.uni-wuerzburg.de
From: Rainer Joswig
Subject: Re: Apply-macro?
Date: 
Message-ID: <joswig-1511982202370001@194.163.195.67>
In article <·················@informatik.uni-wuerzburg.de>, Johannes Beck
<····@informatik.uni-wuerzburg.de> wrote:

> Rainer Joswig schrieb:
> > 
> > In article <·············@cs.uu.nl>, Arend-Jan de Groote
<·····@cs.uu.nl> wrote:
> > 
> > > I really enjoy reading this group, and I'm glad I finally have a
> > > question that's worth asking:
> > >
> > > What I want is to call the macro 'or' with the elements of a list 'lst'.
> > >
> > > If it were a function I'd just say (apply fn lst).
> > > Is there a macro-equivalent to apply?
> > 
> > No.
> 
> Allegro (at least ACL 3.0 & 5.0 on windows) has a
> mapply and mfuncall which are the same as apply and funcall
> only for macros. Maybe you ask Franz for the implementation
> of these...

Doesn't make that much sense for me. Macros are
compile-time transformations. mapply can't be the
same as apply.

-- 
http://www.lavielle.com/~joswig
From: David Bakhash
Subject: Re: Apply-macro?
Date: 
Message-ID: <cxj7lwwe3ha.fsf@engc.bu.edu>
Johannes Beck <····@informatik.uni-wuerzburg.de> writes:

> > In article <·············@cs.uu.nl>, Arend-Jan <·····@cs.uu.nl> wrote:
> > 
> > > I really enjoy reading this group, and I'm glad I finally have a
> > > question that's worth asking:
> > >
> > > What I want is to call the macro 'or' with the elements of a list 'lst'.
> > >
> > > If it were a function I'd just say (apply fn lst).
> > > Is there a macro-equivalent to apply?

If you really want to do that, just use the functional form of `or'
which is (almost) `some':

(apply #'or some-list) ==> (funcall #'some #'identity l)

I think that will work for you.

I would try using loop, with `thereis':

(loop for element in some-list
      thereis element)

I think something like that can work, and it can easily be made into a 
function.

dave
From: Nick Levine
Subject: Re: Apply-macro?
Date: 
Message-ID: <365AB237.478BFE94@harlequin.co.uk>
David Bakhash wrote:

> If you really want to do that, just use the functional form of `or'
> which is (almost) `some':
>
> (apply #'or some-list) ==> (funcall #'some #'identity l)
>
> I think that will work for you.

I don't think anybody replied to this yet...

The problem (as I see it) is that this blurs the distinction between the function
SOME and the macro OR. Functions evaluate all their arguments. Macros need not. A
call of the form
    (apply #'or some-list)
looks to me as if every element in some-list has already been evaluated - not at
all the same as
    (or some-thing
        some-other-thing
        ...)

Etc.

- n
From: Kelly Murray
Subject: Re: Apply-macro?
Date: 
Message-ID: <364220CE.3C60E46D@IntelliMarket.Com>
Arend-Jan de Groote wrote:
> What I want is to call the macro 'or' with the elements of a list 'lst'.

Anytime you need a macro as a function, you can often just write
a function that uses the macro.  In the OR case, it's slightly more
complex than that, but because OR is such a basic operation,
there are probably more than a dozen ways to code the wanted 
result, if not hundreds.  You need to recast the problem
as asking if the list contains a non-nil element:
 
  (find-if-not #'null lst)

I suggest it is coded as a loop so it's easy to understand
and modify later:

 (loop for val in lst 
    do
    (if val (return t))))
    
If you take a step back, you might simply get this answer 
while the list in question is created.  This is exactly why
LOOP is good --- if it was used to create the list, that loop
could be changed to track whether any element was non-nil.
Compare this to a function which is called to return a list,
now you must scan over it again to get new information.

-Kelly Murray  ···@intellimarket.com
 $500 reward for a CommonLisp JPEG encode/decoder utility
From: Kent M Pitman
Subject: Re: Apply-macro?
Date: 
Message-ID: <sfwg1bxydct.fsf@world.std.com>
Kelly Murray <···@IntelliMarket.Com> writes:

>  (loop for val in lst 
>     do
>     (if val (return t))))

Actually, (loop for val in lst thereis val) is the OR thing,
and       (loop for val in lst always  val) is the AND thing
if you prefer to use loop.

It even does the right thing with the OR'd return value in THEREIS,
i.e., (loop for x in '(nil nil 3 4) thereis x) => 3

I still tend to use SOME and EVERY but not for any principled reason.
The reason there are several tools is to accomodate personal taste.
 --Kent
From: Kelly Murray
Subject: Re: Apply-macro?
Date: 
Message-ID: <364236AE.33B1B5E7@IntelliMarket.Com>
Kent M Pitman wrote:
> 
> Kelly Murray <···@IntelliMarket.Com> writes:
> 
> >  (loop for val in lst
> >     do
> >     (if val (return t))))
> 
> Actually, (loop for val in lst thereis val) is the OR thing,
> and       (loop for val in lst always  val) is the AND thing
> if you prefer to use loop.
> 

Use of fancy LOOP features is most definitely NOT my preference.
I hope to someday soon describe and supply an implementation 
that has exactly what features I endorse as part of the 
definition of the SilkScript language. 

-Kelly Murray  ···@intellimarket.com
 $500 reward offered for a CommonLisp JPEG encode/decoder utility