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

时间:2012-11-03 21:21:39

标签: common-lisp lambda clisp

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

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

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

这样呢

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

我理解#'表示一个函数。所以我的问题是,它是某种惯例还是推荐的做法?如果我不使用#'为lambda添加前缀,可能会出错吗?是否依赖于实现?

1 个答案:

答案 0 :(得分:20)

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
)

但是这里(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

LAMBDA宏

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

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

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

FUNCTION特殊操作符

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

Common Lisp中需要FUNCTION运算符,因为它有值,函数和其他一些东西的单独命名空间。它是一个所谓的 Lisp-2 ,甚至是 Lisp-n ,有两个或更多名称空间。

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

Common Lisp的内置语法支持

((lambda (foo) foo) 10)。请参阅Lambda Forms

<强>混淆

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