Is it necessary to use lambda symbol in Common Lisp?

103 Views Asked by At

I've been reading Paul Graham's ANSI Common Lisp recently, where he mentions

In Common Lisp, you can express functions as lists, but they are represented internally as distinct function objects. So lambda is no longer really necessary.

in chapter 2. However, if I omit the lambda symbol, I am unable to compile a correct program.

I try to calculate the Lisp function: (((x) x) 1 ) instead of ((lambda (x) x) 1 ), which should be same as the ANSI Common Lisp said. However, the code without lambda is unable to compile.

3

There are 3 best solutions below

0
Shawn On

The full section from chapter 2 of ACL, which is available on Paul Graham's webpage about the book.

What is Lambda?
The lambda in a lambda expression is not an operator. It is just a symbol. [3] In earlier dialects of Lisp it had a purpose: functions were represented internally as lists, and the only way to tell a function from an ordinary list was to check if the first element was the symbol lambda.
In Common Lisp, you can express functions as lists, but they are represented internally as distinct function objects. So lambda is no longer really necessary. There would be no inconsistency in requiring that functions be denoted as

((x) (+ x 100))  

instead of

(lambda (x) (+ x 100))

but Lisp programmers were used to beginning functions with the symbol lambda, so Common Lisp retained it for the sake of tradition.

(Emphasis added).

He's speaking hypothetically here, about how the language could have had different syntax for defining functions instead of using lambda like it does. As Will mentioned in a comment, at least one other Lisp dialect does accept the lambda-less form. Common Lisp, however, requires it.

0
ignis volens On

Shawn's answer gets across what I think is Graham's point.

But it's worth noting that Graham is simply wrong about this

He's wrong because there is nothing to prevent a Lisp which represents functions as lists using a syntax like ((x y) x) to denote a function, so long as it is a lisp-2.

So lambda is always a choice in such a Lisp.

If you want to allow the equivalent of ((lambda (...) ...) ...) this is perfectly possible in such a Lisp: ((lambda (x y) x) 1 2) becomes (((x y) x) 1 2) and note that this can't denote a function since the first element is not a valid lambda list: it must therefore be the application of an anonymous function.

However note in a Lisp-1, such a representation is not possible. An expression like ((x y) x) in such a lisp means: 'find the value of x which should be a function, call it with an argument which is the value of y and call the return value with an argument which is the value of x'.

So a Lisp-2 which wants not to be gratuitously incompatible with Lisp-1s should probably use lambda the way CL does.


As an example of how it is perfectly possible to have functions expressed in other ways in CL, here is how you might do that:

(defmacro fn (form)
  (etypecase form
    (symbol
     `(function ,form))
    (cons
     (let ((thing (first form)))
       (cond
        ((member thing '(lambda setf))
         `(function ,form))
        ((and (listp thing)
              (or (null thing)
                  (symbolp (first thing))))
         `(function (lambda ,thing ,@(rest form)))))))))

(defun read-function-form (stream char prefix)
  (declare (ignore char prefix))
  `(fn ,(read stream)))

(set-dispatch-macro-character 
 #\# #\'
 #'read-function-form)

And now

> (funcall #'((x) x) 1)
1
0
Rainer Joswig On

Lambda expressions in the Common Lisp standard

The Common Lisp standard has a glossary entry lambda expression:

lambda expression n. a list which can be used in place of a function name in certain contexts to denote a function by directly describing its behavior rather than indirectly by referring to the name of an established function; its name derives from the fact that its first element is the symbol lambda.

There are no ways to denote such a function without using a lambda symbol.

The lambda expression syntax is also documented. See for example here: lambda.

This is the EBNF syntax for lambda expressions:

lambda lambda-list [[declaration* | documentation]] form*

An example would be:

(lambda (a &optional (b 1))
  (declare (type number a b))
  "Increments the value of a by b"
  (+ a b))

Where can I use these lambda expressions?

Lambda expressions are used in two places in the language:

  • Inside function forms: (function (lambda (x) (1+ x))), which can also be written as #'(lambda (x) (1+ x)).

  • There is also a hardwired Common Lisp syntax to call them directly ((lambda (x) (1+ x)) 41). Here the lambda expression (lambda (x) (1+ x)) is called with the argument 41.