From: Bruce Butterfield
Subject: funcall
Date: 
Message-ID: <1106940467.574872.116030@c13g2000cwb.googlegroups.com>
Why does funcall allow either a symbol or a function as it's first
argument? Is this a convenience or is there a more interesting
rationale? It seems odd that

(funcall '+ 1 2 3)

and

(funcall #'+ 1 2 3)

both return the same value. It seems inconsistent to this noob.


The hyperspec says:

funcall applies function to args. If function is a symbol, it is
coerced to a function as if by finding its functional value in the
global environment.

From: jtdubs
Subject: Re: funcall
Date: 
Message-ID: <1106943251.452070.15050@c13g2000cwb.googlegroups.com>
Bruce Butterfield wrote:
> Why does funcall allow either a symbol or a function as it's first
> argument? Is this a convenience or is there a more interesting
> rationale? It seems odd that
>
> (funcall '+ 1 2 3)
>
> and
>
> (funcall #'+ 1 2 3)
>
> both return the same value. It seems inconsistent to this noob.
>
>
> The hyperspec says:
>
> funcall applies function to args. If function is a symbol, it is
> coerced to a function as if by finding its functional value in the
> global environment.

CL-USER 1 > (defun foo (x y) (+ x y))
FOO

CL-USER 2 > (flet ((foo (x y) (* x y)))
.              (values (funcall #'foo 3 4)
.                      (funcall 'foo 3 4)))
12
7

The #' is syntactic-sugar for (function ...).  And ' is sugar for
(quote ...).  So, your choice is really between:

(funcall (function foo) ...)
and
(funcall (quote foo) ...)

Here's a snipit of the CLHS entry for the "function" special operator:
(http://www.lisp.org/HyperSpec/Body/speope_function.html#function)

"The value of function is the functional value of name in the current
lexical environment."

And, as you quoted from the CLHS for funcall, if you pass a symbol you
get the current binding in the global environment.

So, #' gives you the lexical binding and ' gives you the global
binding.  So, #' will notice lexical definitions defined by flet and
labels, but ' won't.

I'm not the best person to explain this next bit.  I'm sure Paul or
Duane or someone can give you a much better worded explanation, but...

Basically, any lexical binding you have in your code, whether via let
or flet or labels, has it's name thrown out by the compiler.  There is
no reason to keep it around.  If you define some variable bindings with
let, then references to those variables within the let just get
compiled to reference the binding itself.  It doesn't need to know that
it was called "x" or "foo" at run-time.  Same with flet and labels.

So, when the compiler see's a (funcall #'foo ...) inside of a (flet
((foo ...)) ...) it just compiles the funcall to call the function
defined by the flet.  It doesn't matter whether it was called foo or
not after it is compiled.

However, if you say (funcall 'foo ...), that means that funcall has to,
at run-time, find the current function binding for the symbol "foo".
As the lexical bindings have lost their names, it has no choice but to
find the global binding as defined by defun.

I hope this makes some sense.  If I have a piece of that wrong or
worded poorly I hope someone will jump in and set me straight.
Justin Dubs
From: Duane Rettig
Subject: Re: funcall
Date: 
Message-ID: <48y6dgrur.fsf@franz.com>
"jtdubs" <······@eos.ncsu.edu> writes:

> I'm not the best person to explain this next bit.  I'm sure Paul or
> Duane or someone can give you a much better worded explanation, but...

 [ ... ]

> I hope this makes some sense.  If I have a piece of that wrong or
> worded poorly I hope someone will jump in and set me straight.
> Justin Dubs

Looked fine to me.

-- 
Duane Rettig    ·····@franz.com    Franz Inc.  http://www.franz.com/
555 12th St., Suite 1450               http://www.555citycenter.com/
Oakland, Ca. 94607        Phone: (510) 452-2000; Fax: (510) 452-0182   
From: Steven M. Haflich
Subject: Re: funcall
Date: 
Message-ID: <P3fLd.18484$5R.1268@newssvr21.news.prodigy.com>
jtdubs wrote:

> However, if you say (funcall 'foo ...), that means that funcall has to,
> at run-time, find the current function binding for the symbol "foo".
> As the lexical bindings have lost their names, it has no choice but to
> find the global binding as defined by defun.

The basic argument of the above paragraph concerning lexical and global
function namespaces is incorrect, but some details are bogus.
Specifically, there is no guarantee that the code will resolve the
global function binding at run time.  ANS 3.2.2.3 Semantic Constraints
gives specific license for the compiler to make compile time assumptions
about calls to "a named function that is defined in the same file."  It
is less clear whether the compiler is allowed to inline functions from
other files, absent an inline declaration.  It is also unclear whether
this "same file" clause might have been rewritten as "same
with-compilation-unit" when that macro was added to the language.  I
don't remember whether that was specifically considered.

But I wanted to caution against equating the global environment with
run-time lookup.  The two have little to do with one another.
From: Barry Margolin
Subject: Re: funcall
Date: 
Message-ID: <barmar-ADF3D4.22134030012005@comcast.dca.giganews.com>
In article <···················@newssvr21.news.prodigy.com>,
 "Steven M. Haflich" <·················@alum.mit.edu> wrote:

> jtdubs wrote:
> 
> > However, if you say (funcall 'foo ...), that means that funcall has to,
> > at run-time, find the current function binding for the symbol "foo".
> > As the lexical bindings have lost their names, it has no choice but to
> > find the global binding as defined by defun.
> 
> The basic argument of the above paragraph concerning lexical and global
> function namespaces is incorrect, but some details are bogus.
> Specifically, there is no guarantee that the code will resolve the
> global function binding at run time.  ANS 3.2.2.3 Semantic Constraints
> gives specific license for the compiler to make compile time assumptions
> about calls to "a named function that is defined in the same file."  It
> is less clear whether the compiler is allowed to inline functions from
> other files, absent an inline declaration.  It is also unclear whether
> this "same file" clause might have been rewritten as "same
> with-compilation-unit" when that macro was added to the language.  I
> don't remember whether that was specifically considered.
> 
> But I wanted to caution against equating the global environment with
> run-time lookup.  The two have little to do with one another.

The only time I think this could make a difference would be if you 
actually put the quoted function name in the FUNCALL form.  Except 
perhaps as a result of macro expansion, this seems like a silly thing to 
do, since 

(funcall 'foo ...)

is essentially the same as

(foo ...)

unless there's a local function binding of FOO in scope.  FUNCALL is 
virtually always called using a computed function object or name.  And 
if the computation returns a symbol, its global function binding has to 
be looked up at run-time.

-- 
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
From: David Sletten
Subject: Re: funcall
Date: 
Message-ID: <%IwKd.3450$WD4.3049@twister.socal.rr.com>
Bruce Butterfield wrote:

> Why does funcall allow either a symbol or a function as it's first
> argument? Is this a convenience or is there a more interesting
> rationale? It seems odd that
> 
> (funcall '+ 1 2 3)
> 
> and
> 
> (funcall #'+ 1 2 3)
> 
> both return the same value. It seems inconsistent to this noob.
> 
> 
I think 'superfluous' would be more appropriate than 'inconsistent'. 
However, it's not superfluous as I will show.

The reason for this behavior is that not every function exists in the 
global environment:
(defun pung () 'foo)

(flet ((pung () 'bar))
   (print (funcall 'pung))
   (print (funcall #'pung)))
This outputs:
FOO
BAR

The second FUNCALL is given the local function object corresponding to 
PUNG within the FLET context. The first one has to find the global 
function associated with the symbol PUNG, i.e., via (SYMBOL-FUNCTION 'PUNG).

This type of behavior (shadowing functions) is probably not used very 
often. However, bear in mind when using FLET/LABELS that FUNCALL needs 
function objects (#') not names (symbols) to access those local 
functions. A common mistake would be something like:
(dolist (f '(pung foo bar))
   (funcall f ...))
Instead you might need:
(dolist (f (list #'pung #'foo #'bar))
   (funcall f ...))

David Sletten

David Sletten
From: Marco Baringer
Subject: Re: funcall
Date: 
Message-ID: <m2oef9gwkf.fsf@soma.local>
"Bruce Butterfield" <···@entricom.com> writes:

> Why does funcall allow either a symbol or a function as it's first
> argument? Is this a convenience or is there a more interesting
> rationale?

it's just different. funcall can be passed either the name of a
function, in which case a lookup is done at evecution time in the
global name space, or a function object (what #'+ returns).

condsider this:

(defun foo () 'global)

(flet ((foo () 'local))
  (list (funcall #'foo) (funcall 'foo)))
==>
(LOCAL GLOBAL)

and then this:

(defun foo () 'first)

(defvar sharp-f #'foo)
(defvar quote-f 'foo)

(defun foo () 'second)

(list (funcall sharp-f) (funcall quote-f))
==>
(FIRST SECOND)

hope this helps.

-- 
-Marco
Ring the bells that still can ring.
Forget the perfect offering.
There is a crack in everything.
That's how the light gets in.
	-Leonard Cohen
From: Barry Margolin
Subject: Re: funcall
Date: 
Message-ID: <barmar-9E2694.21342628012005@comcast.dca.giganews.com>
In article <························@c13g2000cwb.googlegroups.com>,
 "Bruce Butterfield" <···@entricom.com> wrote:

> Why does funcall allow either a symbol or a function as it's first
> argument? Is this a convenience or is there a more interesting
> rationale? It seems odd that
> 
> (funcall '+ 1 2 3)
> 
> and
> 
> (funcall #'+ 1 2 3)
> 
> both return the same value. It seems inconsistent to this noob.

(defun some-function ()
  'old-definition)

(defvar *func1* 'some-function)
(defvar *func2* #'some-function)

(defun some-function ()
  'new-definition)

(funcall *func1*) => NEW-DEFINITION
(funcall *func2*) => OLD-DEFINITION

So if you want to save away function information, and have it track 
redefinitions, you need to use the name rather than the function object.

-- 
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***