Summary
(function foo)
is a special form, returning a function object. Here retrieved from the name foo
. We use it to get a function object.
(funcall foo)
is used to call functions passed as an argument - here the variable value of foo
.
funcall = FUNction CALL = call a function.
We use it to call a function object.
Details
Here is a closure, which applies a predicate to a number n and, if correct, returns (list n), else nil:
(defun all-those (predicate)
(lambda (n)
(if (funcall predicate n) (list n))))
No, that's not a closure. all-those
returns a closure, but itself it isn't one.
? #'all-those
#<Compiled-function ALL-THOSE #x302000C9631F>
? (all-those #'evenp)
#<COMPILED-LEXICAL-CLOSURE (:INTERNAL ALL-THOSE) #x302000E5ECFF>
I understand that I need to call funcall to turn this closure into a function.
A closure is a function object.
? (functionp (all-those #'evenp))
T
Note: all closures are also function objects. Not all function objects are closures.
A closure is a function and associated variable bindings. It is a function object.
Note that anonymous functions are not necessarily closures. (function (lambda () ()))
does not return a closure, since there are no variable bindings. You could say that it is a closure with empty bindings, but in CL speak that's not called a closure.
Note that in standard Common Lisp there is no way to determine if a function object is actually a closure and there is no way to access its bindings via variable names.
I understand that I need to call funcall to turn this closure into a function.
funcall
is used to call function objects (or function objects which it will retrieve from a symbol's function value) with arguments.
Remember, there are various ways to call a function:
call a named global function: (foo bar baz)
call a named lexical function: (foo bar bar)
call a named global function via a symbol: (funcall 'foo bar baz)
call a function object from a variable value: (funcall foo bar baz)
call a function object from a function name (lexical or global): (funcall #'foo bar baz)
call an anonymous function object: (funcall (function (lambda (foo) foo)) 'bar)
or (funcall #'(lambda (foo) foo) 'bar)
or (funcall (lambda (foo) foo) 'bar)
call an anonymous function: ((lambda (foo) foo) 'bar)
Then there is APPLY
which is similar to FUNCALL
but takes the arguments from a list.
(apply #'+ 1 2 3 (list 4 5 6)) is similar to (funcall #'+ 1 2 3 4 5 6)
FUNCALL itself is a function. All its argument forms will be evaluated. The first argument needs to evaluate to a symbol or a function object. funcall
will call the function object (or the function object retrieved from the symbols's function value with arguments.
FUNCTION is a special operator. It is syntax. It is not a function itself. FUNCTION
expects a symbol or a lambda expression as its subform. A FUNCTION
form returns a function object, corresponding to the symbol (either from a global function or a lexical function) or to the lambda expression.
? (defun foo (bar) (list bar 'baz))
FOO
? (function foo) ; a function object from the global function
#<Compiled-function FOO #x302000CC0D1F>
? #'foo ; the same, differently written
#<Compiled-function FOO #x302000CC0D1F>
? (funcall #'foo 42) ; calling the function object
(42 BAZ)
? (funcall 'foo 42) ; calling the symbol-function of the symbol
(42 BAZ)
? (funcall (symbol-function 'foo) 42) ; as above
(42 BAZ)
? (flet ((foo (arg) (list arg :foo))) ; a local lexical function
(list (foo 43) ; calling the local lexical function
(funcall #'foo 42) ; calling a function object,
; from the local lexical function
(funcall 'foo 41))) ; calling the symbol-function of the symbol
((43 :FOO) (42 :FOO) (41 BAZ))
mapcar
(1)   directly i.e. passing a function object. In this case I don't need to sharp quote because the function object is "already there". Which is the case in my example. or (2)   I can pass a symbol with a function bound to it. In this case I need to (sharp) quote in order to get to the function object:(mapcar #'a-symbol …)
Thanks again. – Hebrews