In order to understand what the symbol funcall
means I have checked out its documentation. If I understand it right after reading the docs this symbol represents a function which in my eyes can be always easily removed from the elisp expression without changing the outcome:
(funcall '+ 1 2) ; returns 3
(+ 1 2) ; returns 3
Also in the code example provided in the funcall
function documentation the expression works OK after skipping funcall
from it:
(funcall 'cons 'x 'y) ;returns (x . y)
(cons 'x 'y) ;returns (x . y)
What is the difference between the two code versions giving funcall
the right to exist?
Is it just for fun there in order to be able to obfuscate:
(+ 3 2)
expressing it as:
(defun 3+ (x) (+ x 3)) (3+ 2)
(funcall (lambda (x) (+ x 3)) 2)
;; with finally:
(funcall (setq 3+ (lambda (x) (+ x 3))) 2)
?
Or is it there to fix the problem if someone erroneously misused the value slot of a symbol to store there a function?
In other words: is there a code example able to demonstrate a meaningful usage of funcall
?
@Drew : elisp is able to distinguish between the value and the function "slots" of a symbol without usage of funcall
from the context of symbols usage. Run following piece of code in Emacs 29 to see it yourself:
(setq f 2)
(defun f () 3)
(message "val: %s func: %s symb: %s" f (f) 'f)
which gives:
"val: 2 func: 3 symb: f"
@Drew : to my knowledge in elisp ALL symbols and expressions are ALWAYS evaluated. Also 'f
becomes evaluated and it equals to f
only because '
is a syntactical sugar for a special form quote
returning f
as the value of to it passed parameter without evaluating it.
funcall
is a function, which in Lisp means that all of its args are evaluated. Consider that you can pass a variable whose value is a function to afuncall
sexp. That sexp can then invoke whatever function is the variable's value. You can, e.g., usefuncall
in a higher-order function that takes a function as one of its arguments, and that invokes that function. This is how higher-order functions such asmapcar
work. – Drew Apr 17 '23 at 01:53C-h i
). – Drew Apr 17 '23 at 01:53(a 42)
to evaluate variablea
to get a function and then invoke that function with argument 42. With Lisp-2 you cannot. Instead you have to write(funcall a 42)
to accomplish the same thing. This is because in a Lisp-2 a symbol such asa
can have a value as a variable (that value could of course be a function) and a completely different "value" as a function.(symbol-value 'a)
gives the value of symbola
as a variable.(symbol-function 'a)
gives its value as a function. – Drew Apr 17 '23 at 01:59funcall
would be enough. Not every command/instruction/function/keyword in a programming language is for actual meaningful usage there - some are just for the sake of some kind of completeness. – Claudio Apr 17 '23 at 02:16(funcall a 42)
It's not true for me. Just run the example I gave in the update to see it yourself. – Claudio Apr 17 '23 at 02:35funcall
. Why you would want to store a function in the value cell of a symbol? See my answer for a "real" example. – NickD Apr 17 '23 at 04:02((lambda (...) ...) ...)
, see 10.2.4: “This form is rarely used and is now deprecated.” – shynur Apr 17 '23 at 07:09funcall
(orapply
or etc.). The point is that you cannot just put the variable in the car of a list and then evaluate that list. With Lisp-2, the car of a list that's evaluated is not evaluated as a variable. Instead, thesymbol-function
value of that symbol is used as the function to invoke. IOW, you can't just use(f arg1...)
to invoke the function that's the value of variablef
on the args. This is the difference between Lisp-1 and Lisp-2. – Drew Apr 17 '23 at 23:16mapcar
definition in Lisp, for example (it's very simple. You really need to look around a bit, IMO. Do yourself a favor and open the Into to Elisp manual... – Drew Apr 17 '23 at 23:18