Search code examples
namespaceslispcommon-lisp

Using parameters as operators in LISP lambda function (The Roots of Lisp)


I'm teaching myself lisp, mostly because I like the idea of being able to build programs from small axiomatic blocks. Learning lisp is a hobby project for me because i) it seems fun and ii) I want to see if it really does let me look at problems in a new way. To this end I'm working through Paul Graham's The Roots of Lisp article. I am using the SBCL implementation, though my issue occurs on other implementations also. I've encountered a problem trying to use parameters as operators in a lambda function:

((lambda (f) (f '(b c))) 
 '(lambda (x) (cons 'a x)))

Per section 2 of The Roots of Lisp, this should evaluate to (a b c). This makes sense, the second lambda is a parameter to the first. Assuming my understanding is correct, the expression simplifies to:

((lambda (x) (cons 'a x)) '(b c))

Fine. Running the latter works as expected. However, running the former, unsimplified, expression results in the error: The function COMMON-LISP-USER::F is undefined. Other SO questions (here and here) lead me to believe this is something to do with the function vs variable namespaces in CL, and I've tried the #' syntax in various ways, but I can't seem to get it to work the way I'd expect. What should I do?

Thanks!


Solution

  • You have two errors here:

    1. You shouldn't quote this expression '(lambda (x) (cons 'a x)), it has to evaluate to function.
    2. As Common Lisp is Lisp-2, you have to use funcall to get the function value of a symbol.

    Correct code:

    ((lambda (f) (funcall f '(b c))) 
     (lambda (x) (cons 'a x)))