Why do we have to use funcall
to call higher order functions in Common Lisp? For example, why do we have to use:
(defun foo (test-func args) (funcall test-func args))
instead of the simpler:
(defun bar (test-func args) (test-func args))
Coming from a procedural background, I'm a bit surprised by that since the languages I'm more used to (e.g. Python, C#) don't need the distinction. In particular, on the source level at least, the C# compiler transforms it to something like func.invoke()
.
The only problem I see is that this would mean we couldn't call a global function test-func
anymore because it'd be shadowed, but that's hardly a problem.
Description: 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.
In Common Lisp apply is a function that applies a function to a list of arguments (note here that "+" is a variadic function that takes any number of arguments): (apply #'+ (list 1 2)) Similarly in Scheme: (apply + (list 1 2))
Strictly speaking, funcall
would not be needed, but there are some lisps (list-2 implementations, such as Common Lisp) that separate the variable name space of the function name space. List-1 implementations (e.g. Scheme) do not make this distinction.
More specifically, in your case, test-func
is in the variable name space.
(defun foo (test-func args) (funcall test-func args))
Therefore you need a construct that actually searches the function object associated with this variable in the variable name space. In Common Lisp this construct is funcall
.
See also this answer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With