Why does mapcar in lisp take a name instead of function?

164 Views Asked by At

I am going through a lisp book and I am looking at mapcar, my question is why is that this is valid:

> (mapcar #'+ '(1 2) '(3 4))

but this one isn't:

(mapcar + '(1 2) '(3 4))

in other words, is there a reason it was decided in lisp that the first argument to mapcar cannot be the function itself, and has to be its name? what purpose does this serve?

2

There are 2 best solutions below

3
On BEST ANSWER

is there a reason it was decided in lisp that the first argument to mapcar cannot be the function itself, and has to be its name? what purpose does this serve?

It's just that in something like Common Lisp, the identifier + has multiple different purposes. It is a variable, a function, plus various other things.

writing + means the variable. It is used by the read eval print loop. The value of + is the last form that was evaluated, the value of ++ is the previous value of +, and the value of +++ is the previous value of ++.

To tell Common Lisp that you want to use the function value of an identifier +, one has to write (function +) or shorter #'+.

Thus

(mapcar (function +) '(1 2) '(3 4))

or shorter

(mapcar #'+ '(1 2) '(3 4))

actually means call mapcar with the function + and the lists (1 2) and (3 4)

There are two other ways to use the function +.

(mapcar '+ '(1 2) '(3 4))

Above will have Lisp retrieve the global function value of the symbol +.

Fourth, we can also have the function object be a part of the source code.

1
On

#'+ is a function. Common Lisp is what's called a 'lisp 2', which means that it has two namespaces: during evaluation of a compound form, like (+ a b), the function position is looked up in the function namespace while the other positions are looked up in the value namespace. This means that, for instance (append list list) does not make a list whose two elements are the list function: it makes a list whose two elements are whatever list happens to be bound to as a value.

But sometimes you need to get the function value of a name in a value position: an example is in the first argument of mapcar. To do that there is a special operator, function: (mapcar (function +) x y) adds the elements of two lists. Like quote, function has a read macro, which is #'.

(To make this more fun, mapcar actually expects a function designator so you can use the nsme of a function: (mapcar '+ x y) will work, although it is a bit horrid.)