[comp.lang.lisp] Problem with

d-yang@cs.columbia.edu (David Yang) (02/15/91)

Maybe I'm missing something, but I don't see why (apply #'or '(t nil t nil))
shouldn't work.  What am I missing?

Thanks in advance for any help,
David Yang
d-yang@cs.columbia.edu

Script started on Fri Feb 15 01:40:19 1991
$ lisp
sh: lisp: not found
$ ../lisp
;;; 
;;; Sun Common Lisp, Development Environment 3.0.1, 27 October 1988
;;; Sun-4 Version for SunOS 4.0 
;;;
;;; Copyright (c) 1985, 1986, 1987, 1988 by Sun Microsystems, Inc., All Rights Reserved
;;; Copyright (c) 1985, 1986, 1987, 1988 by Lucid, Inc., All Rights Reserved
;;;
;;; This software product contains confidential and trade secret
;;; information belonging to Sun Microsystems.  It may not be copied
;;; for any reason other than for archival and backup purposes.

> (apply #'or '(t nil t nil))
>>Error: OR called with 4 arguments, but only 2 arguments are allowed

OR:
   Required arg 0 (FORM): T
   Required arg 1 (ENVIRONMENT): NIL
:C  0: Ignore extra arguments
:A  1: Abort to Lisp Top Level

-> (apply #'+ '(1 2 3 4))
10
-> (quit)
$ 

script done on Fri Feb 15 01:41:04 1991

eliot@phoenix.Princeton.EDU (Eliot Handelman) (02/16/91)

In article <1991Feb15.065508.28609@cs.columbia.edu> d-yang@division.columbia.edu (David Yang) writes:
;Maybe I'm missing something, but I don't see why (apply #'or '(t nil t nil))
;shouldn't work.  What am I missing?


CLtL II, pg 145 (from I): "it is illegal for the symbol to be the name
of a macro or special form."

You can use SOME to do the same thing like this:

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

But that's not very idiomatic, since (some #'identity '(t nil t nil))
is equivalent. In short, you probably don't need APPLY here at all.

pld@whopper.lcs.mit.edu (Peter L. DeWolf) (02/16/91)

OR is a macro and therefore can't be used as an argument to APPLY.
--

   Peter L. DeWolf
   Motorola Cambridge Research Center
   pld@mcrc.mot.com -or- pld@abp.lcs.mit.edu

d-yang@cs.columbia.edu (David Yang) (02/16/91)

Thanks for all the helpful and patient answers;
here's one with an alternative.

David

From: Andrew Philpot <philpot@ptolemy.arc.nasa.gov>
;  
;  As someone has no doubt already told you (but hey what's another
;  redundant message):
;  
;  OR is usually a macro, (or I think sometimes a special form) and thus
;  cannot be applied.
;  
;  If you want to map across a list of (assumed) boolean values,
;  returning the first one which is not NIL, or NIL if they all are NIL,
;  try:
;  
;  (some #'identity <list of booleans>)
;  
;  for example
;  
;  > (some #'identity '(t nil t nil))
;  T
;  
;  > (some #'identity '(nil nil () 5 t nil))
;  5
;  
;  > (some #'identity '(nil nil nil nil))
;  NIL
;  
;  etc.
;  
;  Also see EVERY, NOTANY, NOTEVERY.
;  
;  << Andrew >>
;  

jeff@aiai.ed.ac.uk (Jeff Dalton) (02/18/91)

This seems to be a "frequently asked question".

There's a short answer ("OR is a macro, and macros can't be applied")
and a long one (an explanation of why macros such as OR can't be applied).

The long answer is sometimes needed because (1) in some Lisps apply
could be used on macros, and (2) because of (1) or for some other
reason, some people expect it to work, at least for the macros that
are enough like functions.

(I don't want to type in the long answer now, because it's long and
because it's been done before and because this time maybe no one needs
it.  But if anyone every draws up a FAQ list, they might want to bear
this in mind.)

eweb@ccvax.ucd.ie (02/21/91)

In article <1991Feb15.065508.28609@cs.columbia.edu>, (David Yang) writes:
> Maybe I'm missing something, but I don't see why (apply #'or '(t nil t nil))
> shouldn't work.  What am I missing?
> 


I agree that it seems odd that special forms can't be APPLYed or FUNCALLed,
however in your particular example, what you are missing are the functions
EVERY, SOME, NOTANY and NOTEVERY, (CLtL, 1st Ed, page 250).

  (apply #'or list-of-values)     == (some list-of-values)
  (apply #'and list-of-values)    == (every list-of-values)

As for the reason why special forms cannot be FUNCALLed or APPLYe, I reckon
it has to do with the fact that it is unknown which (if any) args are to 
be evaluated or not.

If SOME or EVERY won't do the job, you could use
 (eval (cons 'or list-of-values))....

Eamonn Webster                       eweb@ccvax.ucd.ie
Department of Computer Science       eweb@ccvax.bitnet
University College Dublin            
Belfield
Dublin 4
Ireland

Phone  +353-1-693244 ext 2484        Fax: +353-1-697262 

seb1525@mvs.draper.com ("Stephen E. Bacher") (02/22/91)

In article <47946.27c2d8d3@ccvax.ucd.ie> Eamonn Webster
<eweb@ccvax.ucd.ie> writes:

>I agree that it seems odd that special forms can't be APPLYed or FUNCALLed,
>however in your particular example, what you are missing are the functions
>EVERY, SOME, NOTANY and NOTEVERY, (CLtL, 1st Ed, page 250).
>
>  (apply #'or list-of-values)     == (some list-of-values)
>  (apply #'and list-of-values)    == (every list-of-values)

Wrong - should be:

   (apply #'or list-of-values)     == (some #'identity list-of-values)
   (apply #'and list-of-values)    == (every #'identity list-of-values)

If you don't have the IDENTITY function, use #'(lambda (x) x).

Or (n.p.i.), for the "and" case: (not (member nil list-of-values))

>As for the reason why special forms cannot be FUNCALLed or APPLYe, I reckon
>it has to do with the fact that it is unknown which (if any) args are to
>be evaluated or not.
>
>If SOME or EVERY won't do the job, you could use
> (eval (cons 'or list-of-values))....

NO WAY.  E.g.:

 (setq list-of-values '(a b c d e))
 (apply #'or list-of-values)

 ...pretending for a minute that the above works somehow...

 ==> (apply #'or '(a b c d e))

 But...

 (eval (cons 'or list-of-values))

 ==> (eval (cons 'or '(a b c d e)))
 ==> (eval '(or a b c d e))
 ==> *ERROR* ; if you're lucky

 What would work is

 (eval (cons 'or (mapcar #'(lambda (x) (list 'quote x)) list-of-values))

 The point is, however, that it is usually a bad idea to use EVAL.
 At least in this case it won't fail, since there are no variable
 scoping issues afoul of which to run.  But you take an efficiency hit.

 In general, if you find yourself using EVAL, you're probably taking
 a wrong approach somewhere.

 - SEB

alms@cambridge.apple.com (Andrew L. M. Shalit) (02/23/91)

In article <47946.27c2d8d3@ccvax.ucd.ie> eweb@ccvax.ucd.ie writes:

   As for the reason why special forms cannot be FUNCALLed or APPLYe, I reckon
   it has to do with the fact that it is unknown which (if any) args are to 
   be evaluated or not.

Macros and special forms can be thought of extensions to the compiler.
Once you have compiled code, the macros don't need to exist.  In contrast,
functions are objects, whic exist at run time.  FUNCALL and APPLY operate
on these run-time objects.
--

eweb@ccvax.ucd.ie (03/06/91)

In article seb1525@mvs.draper.com ("Stephen E. Bacher") 

> In article <47946.27c2d8d3@ccvax.ucd.ie> Eamonn Webster
> <eweb@ccvax.ucd.ie> writes:
> 
>>  (apply #'or list-of-values)     == (some list-of-values)
>>  (apply #'and list-of-values)    == (every list-of-values)
> 
> Wrong - should be:
> 
>    (apply #'or list-of-values)     == (some #'identity list-of-values)
>    (apply #'and list-of-values)    == (every #'identity list-of-values)
> 
> If you don't have the IDENTITY function, use #'(lambda (x) x).

Thanks for the correction, I realised that I'd made a mistake the 
moment I had sent the mail, and it was too late.

I was thinking I'd got away with it when the discussion moved on to
the number of primitives that Common Lisp should have.

However he missed my second mistake and introduces one of his own
in my original note I wrote :
>>As for the reason why special forms cannot be FUNCALLed or APPLYe, I reckon
>>it has to do with the fact that it is unknown which (if any) args are to
>>be evaluated or not.
>>
OR and AND are MACROS not SPECIAL FORMS, but the comment still stands.

However the criticism that my use of EVAL doesn't work is invalid.
EVAL is a function, and thus evaluates the argument. So 
> 
>  ==> (eval (cons 'or '(a b c d e)))
>  ==> (eval '(or a b c d e))
>  ==> *ERROR* ; if you're lucky
is wrong.

>  In general, if you find yourself using EVAL, you're probably taking
>  a wrong approach somewhere.
> 
As for the use of eval. Well I occasionally work in other languages
and a common problem is that I want the user to enter not simply a
value, but an expression, (querying a database, for plotting graphs,
entering rules in a rule based traffic simulator).
In other languages you must read the input, parse it and evaluate it.
Referring to program variables is a pain.

In Lisp I can simply evaluate the form, being prepared to beep the user 
if any errors occur.


Eamonn Webster                       eweb@ccvax.ucd.ie
Department of Computer Science       eweb@ccvax.bitnet
University College Dublin            
Belfield
Dublin 4
Ireland

Phone  +353-1-693244 ext 2484        Fax: +353-1-697262