From: Neil Zanella
Subject: funcall question: special operator is not a function
Date: 
Message-ID: <Pine.LNX.4.30.0110190024210.23755-100000@garfield.cs.mun.ca>
Hello,

I would like to know why the lisp funcall construct allows me to apply +
but not or to some operands. Here are some examples:

> (funcall '+ 1 2)
3
> (or T NIL)
T
> (funcall 'or T NIL)

*** - FUNCALL: OR is a special operator, not a function

I would like to know what the difference between a special operator and a
function is in lisp. Theoretically it should be possible to store boolean
operators in a vairable and apply them to some boolean parameters without
knowing which operator is being applied.

Thanks,

Neil

From: Scott McKay
Subject: Re: funcall question: special operator is not a function
Date: 
Message-ID: <oZMz7.132409$vq.29853945@typhoon.ne.mediaone.net>
"Neil Zanella" <········@garfield.cs.mun.ca> wrote in message
·············································@garfield.cs.mun.ca...
>
> Hello,
>
> I would like to know why the lisp funcall construct allows me to apply +
> but not or to some operands. Here are some examples:
>
> > (funcall '+ 1 2)
> 3
> > (or T NIL)
> T
> > (funcall 'or T NIL)
>
> *** - FUNCALL: OR is a special operator, not a function
>
> I would like to know what the difference between a special operator and a
> function is in lisp. Theoretically it should be possible to store boolean
> operators in a vairable and apply them to some boolean parameters without
> knowing which operator is being applied.
>

You can think of a "special operator" as a piece of built-in syntax
or a macro.  Some Lisp implementations implement special operators
using macros.

'or' can't be implemented as a function because its semantics are
"evaluate each of the "parameters" from left to right until one is
not NIL; return the value of that, or return NIL if you get to the
end".  '(or t (setq *foo* 100)) ' will never set *foo* to 100.
From: Kaz Kylheku
Subject: Re: funcall question: special operator is not a function
Date: 
Message-ID: <62Oz7.97117$ob.2191117@news1.rdc1.bc.home.com>
In article <········································@garfield.cs.mun.ca>,
Neil Zanella wrote:
>
>Hello,
>
>I would like to know why the lisp funcall construct allows me to apply +
>but not or to some operands. Here are some examples:
>
>> (funcall '+ 1 2)

You should make that #'+ unless there is a good reason to just use
the symbol. #'+ creates a funcallable object from the + function,
whereas '+ just to refers to the symbol +.

(A symbolic reference *can* have extra flexibility because it is more
loosely coupled to the function; (funcall '+ 1 2) will call whatever
+ refers to at the time of the call, rather than a precooked object).

>I would like to know what the difference between a special operator and a
>function is in lisp.

A function receives its arguments by value, whereas a special operator
has access to unevaluated arguments. 

Special operators and macros cannot be turned into callable objects,
so the applicative operators funcall, apply, mapcar and friends do not
work with macros or operators.

That's just the way it is. It spares the Lisp implementation from having
to be able to represent special operators and macros as callable objects.

If operators could be callable this way, then funcall would have to
suppress the evaluation of its arguments. It would have to evaluate them
if calling a function, or pass them unevaluated if calling some other
type of callable object. This decision would have to be made dynamically,
based on the type of thing being called.

>Theoretically it should be possible to store boolean
>operators in a vairable and apply them to some boolean parameters without
>knowing which operator is being applied.

Or is not only a boolean operator, but it is also a sequencing operator.
It evaluates its argument forms in order until one of them evaluates
non-nil, and then it stops evaluating the rest. The and operator is
similar, except it stops at the first nil. This can be exploited if the
forms have side effects, e.g.

	(and (consp x) (car x)) ;; won't evaluate (car x) if x is not a cons
	                        ;; which would be an error!

For whatever reason, macros and special operators can't be turned
into funcallable objects. 

You can easily make boolean or function which delegates to the operator:

	(defun bool-or (x y) (or x y))

	(funcall #'bool-or t nil)
From: Kent M Pitman
Subject: Re: funcall question: special operator is not a function
Date: 
Message-ID: <sfwvghcmcl6.fsf@world.std.com>
···@ashi.footprints.net (Kaz Kylheku) writes:

> You can easily make boolean or function which delegates to the operator:
> 
> 	(defun bool-or (x y) (or x y))
> 
> 	(funcall #'bool-or t nil)

Or, if it doesn't happen a lot, you can just do it anonymously without
making a named function:

 (funcall #'(lambda (x y) (or x y)) t nil)
From: Lieven Marchand
Subject: Re: funcall question: special operator is not a function
Date: 
Message-ID: <m3lmi78j7g.fsf@localhost.localdomain>
Kent M Pitman <······@world.std.com> writes:

> ···@ashi.footprints.net (Kaz Kylheku) writes:
> 
> > You can easily make boolean or function which delegates to the operator:
> > 
> > 	(defun bool-or (x y) (or x y))
> > 
> > 	(funcall #'bool-or t nil)
> 
> Or, if it doesn't happen a lot, you can just do it anonymously without
> making a named function:
> 
>  (funcall #'(lambda (x y) (or x y)) t nil)

Or, alternatively, you can use SOME as a funcallable equivalent of OR.

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

-- 
Lieven Marchand <···@wyrd.be>
She says, "Honey, you're a Bastard of great proportion."
He says, "Darling, I plead guilty to that sin."
Cowboy Junkies -- A few simple words
From: Kalle Olavi Niemitalo
Subject: Re: funcall question: special operator is not a function
Date: 
Message-ID: <izn3d4gyz1k.fsf@stekt34.oulu.fi>
···@ashi.footprints.net (Kaz Kylheku) writes:

> (A symbolic reference *can* have extra flexibility because it is more
> loosely coupled to the function; (funcall '+ 1 2) will call whatever
> + refers to at the time of the call, rather than a precooked object).

Is there really any difference between these three?

  (func 1 2)
  (funcall #'func 1 2)
  (funcall 'func 1 2)	;assuming FUNC is not lexically fbound

It seems to me that a compiler should treat them exactly the same.
Please see my article <··············@Astalo.y2000.kon.iki.fi>.
From: Kent M Pitman
Subject: Re: funcall question: special operator is not a function
Date: 
Message-ID: <sfw3d4gxhkw.fsf@world.std.com>
Kalle Olavi Niemitalo <···@iki.fi> writes:

> ···@ashi.footprints.net (Kaz Kylheku) writes:
> 
> > (A symbolic reference *can* have extra flexibility because it is more
> > loosely coupled to the function; (funcall '+ 1 2) will call whatever
> > + refers to at the time of the call, rather than a precooked object).
> 
> Is there really any difference between these three?
> 
>   (func 1 2)
>   (funcall #'func 1 2)
>   (funcall 'func 1 2)	;assuming FUNC is not lexically fbound
> 
> It seems to me that a compiler should treat them exactly the same.
> Please see my article <··············@Astalo.y2000.kon.iki.fi>.

(defun func (x y) (+ x 1))
(flet ((func (x y) (- x y)))
 (list (func 1 2) (funcall #'func 1 2) (funcall 'func 1 2)))
returns (-1 -1 3).  Anything that returns a different value can hardly
be called equivalent.

I think (func 1 2) and (funcall #'func 1 2) are semantically the same,
though there may be some implementational wiggle room allowing compiler
macros to treat these slightly differently.

I think (funcall 'func 1 2) and (funcall (symbol-function 'func) 1 2)
are semantically the same.  Additionally, I think both of these are, or
ought to be, immune to INLINE declarations.
From: Kalle Olavi Niemitalo
Subject: Re: funcall question: special operator is not a function
Date: 
Message-ID: <iznu1ww818d.fsf@stekt34.oulu.fi>
Kent M Pitman <······@world.std.com> writes:

> Kalle Olavi Niemitalo <···@iki.fi> writes:
> >   (funcall 'func 1 2)	;assuming FUNC is not lexically fbound

> (flet ((func (x y) (- x y)))
>  (list (func 1 2) (funcall #'func 1 2) (funcall 'func 1 2)))
> returns (-1 -1 3).  Anything that returns a different value can hardly
> be called equivalent.

Well, you broke the assumption there.  I meant the compiler would
check at compile time whether FUNC is lexically bound, and if it
isn't, the three forms should be equivalent.

> I think (funcall 'func 1 2) and (funcall (symbol-function 'func) 1 2)
> are semantically the same.  Additionally, I think both of these are, or
> ought to be, immune to INLINE declarations.

Hm.  That makes sense.
From: Kent M Pitman
Subject: Re: funcall question: special operator is not a function
Date: 
Message-ID: <sfwk7xrvg6x.fsf@world.std.com>
Kalle Olavi Niemitalo <···@iki.fi> writes:

> 
> Kent M Pitman <······@world.std.com> writes:
> 
> > Kalle Olavi Niemitalo <···@iki.fi> writes:
> > >   (funcall 'func 1 2)	;assuming FUNC is not lexically fbound
> 
> > (flet ((func (x y) (- x y)))
> >  (list (func 1 2) (funcall #'func 1 2) (funcall 'func 1 2)))
> > returns (-1 -1 3).  Anything that returns a different value can hardly
> > be called equivalent.
> 
> Well, you broke the assumption there.  I meant the compiler would
> check at compile time whether FUNC is lexically bound, and if it
> isn't, the three forms should be equivalent.

Yes, but when x is false, there really is no difference between

 (if x 1 2)
and
 (or x 2)

I'm not sure what the point of doing a "difference in meaning" comparison
of two notations in a context where you specifically eliminate the main
way in which you'd see the gaping hole that is the difference.  I just 
couldn't bear to put out the words "these are the same" with no further
qualification than that, and with the mere hope that third parties would see
the important qualification and understand its significance.
 
From: Kalle Olavi Niemitalo
Subject: Re: funcall question: special operator is not a function
Date: 
Message-ID: <87k7xqho6q.fsf@Astalo.y2000.kon.iki.fi>
Kent M Pitman <······@world.std.com> writes:

> I'm not sure what the point of doing a "difference in meaning" comparison
> of two notations in a context where you specifically eliminate the main
> way in which you'd see the gaping hole that is the difference.

I was primarily interested in what they do if the function is
later redefined.
From: Roger Corman
Subject: Re: funcall question: special operator is not a function
Date: 
Message-ID: <3bcfe3d8.1177565159@news.callatg.com>
On 19 Oct 2001 08:33:11 +0300, Kalle Olavi Niemitalo <···@iki.fi> wrote:

>···@ashi.footprints.net (Kaz Kylheku) writes:
>
>> (A symbolic reference *can* have extra flexibility because it is more
>> loosely coupled to the function; (funcall '+ 1 2) will call whatever
>> + refers to at the time of the call, rather than a precooked object).
>
>Is there really any difference between these three?
>
>  (func 1 2)
>  (funcall #'func 1 2)
>  (funcall 'func 1 2)	;assuming FUNC is not lexically fbound

I believe these are all identical, sematically, assuming, as you say, FUNC is
not lexically bound.
Note however that by treating them all the same the compiler would be implicitly
inlining the call to the function FUNCALL, which a user can ask to have not
inlined via a NOTINLINE declaration.

Roger
From: Dr. Edmund Weitz
Subject: Re: funcall question: special operator is not a function
Date: 
Message-ID: <m3n12oyu2g.fsf@bird.agharta.de>
Kalle Olavi Niemitalo <···@iki.fi> writes:

> Please see my article <··············@Astalo.y2000.kon.iki.fi>.

You should have written this as
<···················@Astalo.y2000.kon.iki.fi> so users of Gnus or
other capable newsreaders can just follow the link.

(One of the reasons I'm posting this is that I'll get the link this
way... :)

Edi.
From: Kaz Kylheku
Subject: Re: funcall question: special operator is not a function
Date: 
Message-ID: <FyXz7.98686$ob.2221346@news1.rdc1.bc.home.com>
In article <······················@news1.rdc1.bc.home.com>, Kaz Kylheku wrote:
>	(and (consp x) (car x)) ;; won't evaluate (car x) if x is not a cons
>	                        ;; which would be an error!

Christian Ohler noted my silly error here. (car nil) is obviously well
defined, yet nil is an atom.