The #' in common lisp

不想你离开。 提交于 2019-11-28 09:52:32

This is the precise page in Hyperspec which deals with the standard macro character "sharp" followed by "single quote".

To make it simple, this reader macro expands to enclose the following form into (function <form>) s-expression. This effectively tells the parser that the form is callable.

lambda is a macro, which generates the code, which already contains the (function <form>), but historically and for consistency, the alternative form, which is obtained from the reader macro with sharp + quote, is often used too.

Here's Writing lambda expressions in common lisp (another StackOverflow question) which covers in-depth the particular case of (lambda <form>)

Note: *print-pretty* is NIL for these examples.

(defun where (x) 
  #'(lambda (item)
      (> item x)))

In above function where you are creating an anonymous function and you are returning it as a closure (the function plus variable binding for X). Since you are returning it as a value, you have to write (FUNCTION (LAMBDA ...)). #'(lambda ...) is a notation which is shorter, but results in the same - using the reader macro #':

CL-USER 74 > (read-from-string "#'(lambda (foo) (1+ foo))")
(FUNCTION (LAMBDA (FOO) (1+ FOO)))

You can also write:

(defun where (x) 
  (lambda (item)
    (> item x)))

During the definition of Common Lisp it has been added to be able to write above code. It is also identical to the (function (lambda ...)) form. In Common Lisp LAMBDA is macro, which expands into it:

CL-USER 75 > '(lambda (foo) (1+ foo))
(LAMBDA (FOO) (1+ FOO))

CL-USER 76 > (macroexpand '(lambda (foo) (1+ foo)))
(FUNCTION (LAMBDA (FOO) (1+ FOO)))
T

So, LAMBDA is a macro and when the evaluator sees it as in (lambda ...), it expands the form into a (function (lambda ...)) form, which then gets evaluated.

FUNCTION is a special form and when the evaluator sees it, it returns a function object - in the case of (function (lambda (foo) (1+ foo))) it returns the anonymous function as an object:

CL-USER 77 > (function (lambda (foo) (1+ foo)))
#<anonymous interpreted function 406000761C>

So you see that (function (lambda ...)) is the real s-expression notation to get a function object and both #'(lambda ...) (via a reader macro) or (lambda ...) (via a macro) are shorter notations in Lisp source code. It is unusual for a programmer to use the long form. Most (99.999%) use one of the shorter notations in source code.

Btw.: If the evaluator sees function enclosing a name of a function like this (function sin), then it looks up the function binding and returns the corresponding function object:

CL-USER 78 > (function sin)
#<Function SIN 4110083C6C>
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!