19

I am currently reading ANSI Common Lisp by Paul Graham, and I have a question about writing lambda expressions.

Do we need to prefix a lambda expression with #'?. If I write something like this in REPL, it will work fine

> ((lambda (x) (+ x 1)) 1)
  2

so will this

> (mapcar (lambda (x) (+ x x)) '(1 2 3 4))
  (2 4 6 8)

I understand that #' denotes a function. So my question is, is it some sort of convention or recommended practice? Can anything go wrong if I don't prefix lambdas with #', is it implementation dependent?

nrz
  • 10,435
  • 4
  • 39
  • 71
turingcomplete
  • 2,128
  • 3
  • 16
  • 25
  • 2
    You might want to take a look at my [older answer](http://stackoverflow.com/a/3325572/271324). – danlei Nov 03 '12 at 22:45

1 Answers1

27

The LAMBDA expression

(lambda ...) is considered to be a lambda expression only in certain places, like the function form or as the head of a function call. Lambda expressions are not evaluated.

(function              ; special operator FUNCTION
  (lambda () 'foobar)) ; <- this is a lambda expression


(                    ; a function call
 (lambda (foo) foo)  ; <- this is a lambda expression
 'bar                ; argument
)

But here (lambda ...) is a macro form and not a lambda expression:

(funcall             ; calling a function via funcall
 (lambda (foo) foo)  ; this is not a lambda expressions, but the macro lambda
                     ;  as all arguments to FUNCALL it will be
                     ;    macro expanded and evaluated
                     ;  it expands to (function (lambda (foo) foo))
 'bar)               ; argument

The LAMBDA macro

LAMBDA is a macro. It expands (lambda ...) to (function (lambda ...)), which is the equivalent of #'(lambda ...)).

CL-USER > (macroexpand '(lambda (foo) foo))
(FUNCTION (LAMBDA (FOO) FOO))

The macro saves you a bit of writing/reading, that's all. In the first version of Common Lisp (CLtL1) there was no LAMBDA macro. It has been added later and is now a part of ANSI Common Lisp,

The FUNCTION special operator

FUNCTION is a special operator. It expects a function name or a lambda expression. Thus the name or the lambda expression are not evaluated. In fact lambda expressions can't be evaluated at all. Inside FUNCTION, the lambda expression is not a macro form and thus will not be expanded again. The purpose of FUNCTION is to return the corresponding function object which is denoted by the name or by the lambda expression. It returns the function object as a value. With this special operator one can access the function object from global functions and lexical functions.

The FUNCTION operator is necessary in Common Lisp, because it has separate namespaces for values, functions and a few other things. It as a so-called Lisp-2 or even Lisp-n, with two or more namespaces.

Lambda expressions in function position in a function form

((lambda (foo) foo) 10) is supported by built-in syntax for Common Lisp. See Lambda Forms.

Confusing

This is all logical, but confusing. Don't worry you are not alone, but in practice it's not a big deal.

Rainer Joswig
  • 136,269
  • 10
  • 221
  • 346
  • 1
    Thanks, I still don't get why people explicitly write #' before a lambda expression though. – turingcomplete Nov 03 '12 at 21:59
  • 3
    It's a matter of style. Some prefer it, some don't. I prefer it, as it allows to easily identify actual functions used as values. It also makes it easier to replace with an `flet` or `labels` function. Other than lambdas, it also makes a function's definition be looked up. This may be desirable if you don't know if an implementation coerces a [function designator](http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_f.htm#function_designator) upfront, e.g. `(mapcar 'frob my-list)` may lookup `frob`'s `symbol-function` as many times as the elements in `my-list`. – acelent Nov 04 '12 at 00:44
  • 3
    Doug Hoyte provides an argument for not using the #' syntax. Rainer hints at it here; the fact that ((lambda (foo) is built-in syntax, and there's a (lambda macro, means that you can do some interesting things with this duality of syntax when using read macros. Check out Hoyte's cl-ppcre read-macro extension as an example: http://letoverlambda.com/index.cl/guest/chap4.html#sec_4 – Clayton Stanley Nov 04 '12 at 05:23
  • 1
    Regarding claytonstanleys' comment: A quick warning, 'Let Over Lambda' contains some macro techniques which some find questionable in style and maintainability. I love the book and heartily recommend buying it but do be aware that there is deep magic in there and one should think very hard about the end user/coder who will be looking at your code in future. – Baggers Nov 08 '12 at 16:02