在普通的lisp中编写lambda表达式

tur*_*ete 15 lambda clisp common-lisp

我目前正在阅读Paul Graham的ANSI Common Lisp,我有一个关于编写lambda表达式的问题.

我们需要在lambda表达式前加上#'?如果我在REPL中写这样的东西,它会正常工作

> ((lambda (x) (+ x 1)) 1)
  2
Run Code Online (Sandbox Code Playgroud)

这样也会

> (mapcar (lambda (x) (+ x x)) '(1 2 3 4))
  (2 4 6 8)
Run Code Online (Sandbox Code Playgroud)

我明白这#'表示一个功能.所以我的问题是,它是某种惯例还是推荐的做法?如果我不为lambdas添加前缀#',可能出现任何问题,是否依赖于实现?

Rai*_*wig 21

LAMBDA表达

(lambda ...)被认为是仅在某些地方的lambda表达式,如function形式或函数调用的头部.不评估Lambda表达式.

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


(                    ; a function call
 (lambda (foo) foo)  ; <- this is a lambda expression
 'bar                ; argument
)
Run Code Online (Sandbox Code Playgroud)

但这(lambda ...)是一个宏形式而不是lambda表达式:

(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
Run Code Online (Sandbox Code Playgroud)

LAMBDA宏

LAMBDA是一个宏观.它扩展(lambda ...)(function (lambda ...)),相当于#'(lambda ...)).

CL-USER > (macroexpand '(lambda (foo) foo))
(FUNCTION (LAMBDA (FOO) FOO))
Run Code Online (Sandbox Code Playgroud)

宏可以为你节省一些写/读,就是这样.在Common Lisp的第一个版本(CLtL1)中没有LAMBDA宏.它后来被添加,现在是ANSI Common Lisp的一部分,

FUNCTION特殊运算符

FUNCTION是一个特殊的运算符.它需要一个函数名或一个lambda表达式.因此,不评估名称或lambda表达式.事实上,根本无法评估lambda表达式.内FUNCTION,所述lambda表达式宏形式并且因此将被再次扩大.目的FUNCTION是返回由名称或lambda表达式表示的相应函数对象.它将函数对象作为值返回.使用此特殊运算符,可以从全局函数和词法函数访问函数对象.

FUNCTION操作是在Common Lisp的必要,因为它具有价值,功能和一些其他的东西不同的命名空间.它作为一个所谓的Lisp-2甚至是Lisp-n,具有两个或更多名称空间.

Lambda表达式在函数形式的函数位置

((lambda (foo) foo) 10)Common Lisp的内置语法支持.请参阅Lambda表单.

扑朔迷离

这是合乎逻辑的,但令人困惑.不要担心你并不孤单,但在实践中并不是什么大不了的事.

  • 这是一种风格问题.有些人喜欢它,有些则不喜欢.我更喜欢它,因为它允许轻松识别用作值的实际函数.它还可以更容易地用`flet`或`labels`函数替换.除了lambdas之外,它还可以查找函数的定义.这可能是可取的,如果你不知道,如果一个实现一个强制转换[功能标志(http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_f.htm#function_designator)前期,例如'(mapcar"FROB `my-list)`可以像`my-list`中的元素一样多次查找`frob`的`symbol-function`. (3认同)
  • Doug Hoyte提供了一个不使用#'语法的论据.雷纳在这里暗示着它; 事实上((lambda(foo)是内置语法,并且有一个(lambda宏)意味着你可以在使用读取宏时使用这种语法的二元性做一些有趣的事情.查看Hoyte的cl-ppcre读取宏扩展例如:http://letoverlambda.com/index.cl/guest/chap4.html#sec_4 (2认同)