31

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.

nbro
  • 15,395
  • 32
  • 113
  • 196
Voo
  • 29,040
  • 11
  • 82
  • 156
  • 4
    "Hardly a problem" is the crux of the matter. In practice, I find it hardly a problem to call funcall and would be inconvenienced if I had to choose creative/weird names for variables to avoid clashes with CAR, LIST, REST, etc. – Xach Mar 16 '12 at 01:18

3 Answers3

28

Strictly speaking, funcall would not be needed, but there are some lisps (lisp-2 variants, such as Common Lisp) that separate the variable name space of the function name space. Lisp-1 variants (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.

sds
  • 58,617
  • 29
  • 161
  • 278
Diego Sevilla
  • 28,636
  • 4
  • 59
  • 87
22

The majority of Lisps have two namespaces (functions and variables). A name is looked up in the function namespace when it appears as the first element in an S-expression, and in the variable namespace otherwise. This allows you to name your variables without worrying about whether they shadow functions: so you can name your variable list instead of having to mangle it into lst.

However, this means that when you store a function in a variable, you can't call it normally:

(setq list #'+) ; updates list in the variable namespace
(list 1 2 3) => (1 2 3) ; looks up list in the function namespace

Hence the need for funcall and apply:

(funcall list 1 2 3) => 6 ; looks up list in the variable namespace

(Not all Lisps have two namespaces: Scheme is an example of a Lisp with just one namespace.)

Gareth Rees
  • 64,967
  • 9
  • 133
  • 163
  • Yes the advantage of not shadowing functions is nice, but on the other hand we get the special cases for functions.. well I assume since we don't have to worry about bracket positioning in lisp, we need other religious wars ;) Since you and Diego both answered my question nicely, I went with time as a tie-breaker and accepted diego's answer. – Voo Mar 15 '12 at 23:54
-2

In Common Lisp, each symbol can be associated with its symbol-function and its symbol-value, among other things. When reading a list, by default, Common Lisp interprets:

  • arg1 as a function and so retrieves test-func's symbol-function, which is undefined -- thus function bar doesn't work
  • arg2 as something to be evaled -- thus function foo retrieves test-func's symbol-value, which, in your case, happens to be a function
John Pick
  • 5,562
  • 31
  • 31