While continuing my practice with Lisp, I ran into a huge surprise for
me. I was under the impression that the only way to put a function into
a variable was to use the FUNCTION special operator, as in
(funcall #'1+ 1)
However, I found the following code to evaluate without error. Note
that both 1+ and 1- are only QUOTEd, and not FUNCTIONed:
(dolist (num '(1 2 3))
(dolist (func '(1+ 1-))
(format t "~d~%" (funcall func num))))
I then tested using just QUOTE, and found that both (funcall '1+ 1) and
(funcall #'1+ 1) evaluate to the same thing! Is this behavior
guaranteed by the Common Lisp standard, or is it just CLisp acting funny
on me? I'm using Gnu CLisp 2.33.2.
-- MJF
M Jared Finder wrote:
> While continuing my practice with Lisp, I ran into a huge surprise for
> me. I was under the impression that the only way to put a function into
> a variable was to use the FUNCTION special operator, as in
>
> (funcall #'1+ 1)
>
> However, I found the following code to evaluate without error. Note
> that both 1+ and 1- are only QUOTEd, and not FUNCTIONed:
>
> (dolist (num '(1 2 3))
> (dolist (func '(1+ 1-))
> (format t "~d~%" (funcall func num))))
>
> I then tested using just QUOTE, and found that both (funcall '1+ 1) and
> (funcall #'1+ 1) evaluate to the same thing! Is this behavior
> guaranteed by the Common Lisp standard, or is it just CLisp acting funny
> on me? I'm using Gnu CLisp 2.33.2.
That's compliant and required. FUNCALL takes a function designator as its first
argument:
function designator n. a designator for a function; that is, an object
that denotes a function and that is one of: a symbol (denoting the function
named by that symbol in the global environment), or a function (denoting itself).
The consequences are undefined if a symbol is used as a function designator
but it does not have a global definition as a function, or it has a global
definition as a macro or a special form. See also extended function designator.
(If the argument really is a function, it's sometimes useful to declare it
as such, to make FUNCALL more efficient.)
Paul
In article <··············@uni-berlin.de>,
M Jared Finder <·······@hpalace.com> wrote:
> I then tested using just QUOTE, and found that both (funcall '1+ 1) and
> (funcall #'1+ 1) evaluate to the same thing! Is this behavior
> guaranteed by the Common Lisp standard, or is it just CLisp acting funny
> on me? I'm using Gnu CLisp 2.33.2.
See the definition of "function designator" in the language spec.
And also try this:
(defun my-1+ (x) (1+ x))
(flet ((my-1+ (y) (1- y)))
(list (funcall #'my-1+ 10)
(funcall 'my-1+ 10)))
--
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
Barry Margolin wrote:
> In article <··············@uni-berlin.de>,
> M Jared Finder <·······@hpalace.com> wrote:
>
>>I then tested using just QUOTE, and found that both (funcall '1+ 1) and
>>(funcall #'1+ 1) evaluate to the same thing! Is this behavior
>>guaranteed by the Common Lisp standard, or is it just CLisp acting funny
>>on me? I'm using Gnu CLisp 2.33.2.
>
> See the definition of "function designator" in the language spec.
>
> And also try this:
>
> (defun my-1+ (x) (1+ x))
>
> (flet ((my-1+ (y) (1- y)))
> (list (funcall #'my-1+ 10)
> (funcall 'my-1+ 10)))
I think I understand.
In the first call to MY-1+, the function is looked up inside of my code,
resulting in the local binding created in FLET. In the second call to
MY-1+, the function is looked up inside of FUNCALL, resulting in the
global binding created by DEFUN.
Ignoring FLET, is there any advantage to using FUNCTION over QUOTE as a
default way to store a function in a variable?
-- MJF
M Jared Finder <·······@hpalace.com> writes:
> Ignoring FLET, is there any advantage to using FUNCTION over QUOTE
> as a default way to store a function in a variable?
Well, when you use QUOTE you're not storing a function. You're storing
the name of the function. It's just that FUNCALL can take either an
actual function or a function name. This can matter if the function
may get redefined or unbound after you squirell away its name.
Consider:
CL-USER> (defun foo () 'hello)
FOO
CL-USER> (foo)
HELLO
CL-USER> (defparameter *my-fun* 'foo)
*MY-FUN*
CL-USER> (funcall *my-fun*)
HELLO
CL-USER> (fmakunbound 'foo)
FOO
CL-USER> (funcall *my-fun*)
; Evaluation aborted
; attempt to call `FOO' which is an undefined function.
; No value
versus:
CL-USER> (defun foo () 'hello-again)
FOO
CL-USER> (foo)
HELLO-AGAIN
CL-USER> (defparameter *my-fun* #'foo)
*MY-FUN*
CL-USER> (funcall *my-fun*)
HELLO-AGAIN
CL-USER> (fmakunbound 'foo)
FOO
CL-USER> (funcall *my-fun*)
HELLO-AGAIN
-Peter
--
Peter Seibel ·····@javamonkey.com
Lisp is the red pill. -- John Fraser, comp.lang.lisp
"M Jared Finder" <·······@hpalace.com> wrote in message
···················@uni-berlin.de...
> I then tested using just QUOTE, and found that both (funcall '1+ 1) and
> (funcall #'1+ 1) evaluate to the same thing! Is this behavior
Note that they are not always equivalent:
(flet ((1+ (n) (+ 2 n)))
(list (funcall #'1+ 1) (funcall '1+ 1)))
=>(3 2)
--
Coby Beck
(remove #\Space "coby 101 @ big pond . com")
Coby Beck <·····@mercury.bc.ca> wrote:
> Note that they are not always equivalent:
> (flet ((1+ (n) (+ 2 n)))
> (list (funcall #'1+ 1) (funcall '1+ 1)))
> =>(3 2)
Note that local functions with names in the COMMON-LISP package summon
nasal demons of the most vengeful kind:
; in: LAMBDA NIL
; (FLET ((1+ (N)
; (+ 2 N)))
; (LIST (FUNCALL #'1+ 1) (FUNCALL '1+ 1)))
;
; caught ERROR:
; Lock on package COMMON-LISP violated when binding 1+ as a local function.
; See also:
; The SBCL Manual, Node "Package Locks"
; The ANSI Standard, Section 11.1.2.1.2
; compilation unit finished
; caught 1 ERROR condition
Same portably:
(defun foo (x) (+ 1 x))
(flet ((foo (x) (+ 2 x)))
(list (funcall #'foo 1) (funcall 'foo 1)))
=> (3 2)
Cheers,
-- Nikodemus "Not as clumsy or random as a C++ or Java.
An elegant weapon for a more civilized time."