- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试通过Common Lisp:对符号计算的温和介绍这本书来学习 Common Lisp。此外,我正在使用 SBCL、Emacs 和 Slime。
在第 7 章中,作者提出了以下关于 lambda 表达式
的建议:
这让我感到困惑,因为 SBCL 的 REPL 返回:
CL-USER> #'lambda
#<CLOSURE (:MACRO LAMBDA) {1000D736DB}>
显然,作者使用了 Lisp Works(并非 100% 确定)。我认为这与上述差异无关。不过,我认为还是提一下比较好。
我的 SBCL 的 REPL 还为众所周知的宏返回 macro
,例如 和
:
CL-USER> #'and
#<CLOSURE (:MACRO AND) {1000D7365B}>
请注意,append
等“普通”函数的行为是不同的:
CL-USER> #'append
#<FUNCTION APPEND>
此帖here似乎略微触及了 lambda 表达式的非单一性。但是,它没有提及任何关于标记的内容。
我是不是漏掉了 lambda 表达式的本质?
最佳答案
思考这个问题的一种方式是认识到在 CL 中获得词法上明显的函数值的唯一方法是特殊运算符 function
: 如果你想获得与 foo
关联的函数在当前的词汇环境中你必须说(function foo)
:
(flet ((foo (x)
x))
(function foo)
例如。所以function
是特殊的运算符,它可以让您查看函数命名空间中的内容。 function
有一些语法糖,即 #'
, 同理quote
确实(我不打算在下面使用它)。你可以想到函数应用 (f x y)
大约像(<funcall> (function f) x y)
, 其中<funcall>
是一些神奇的东西,它不会像那样被替换掉。
但是您还需要匿名函数,那么,您可以使用 function
同样,它的参数是一个 lambda 表达式:
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. – CLHS
所以匿名函数表示为(function (lambda (...) ...))
.如果你愿意,你可以想到 (lambda (...) ...)
作为函数的“名称”。 (我认为人们不喜欢这个,因为它干扰了匿名函数的想法,但很明显,有一组可数的可能函数“名称”,形式为 (lambda (...) ...)
,你甚至可以枚举这组我认为(这样做与枚举有理数一样繁琐)。
由于函数应用程序中的函数位置已经在函数的命名空间中被解释,((lambda (...) ...) ...)
表示匿名函数应用程序:它或多或少与 (funcall (function (lambda (...) ...) ...)
相同(再次参见 CLHS)。
这就是 CL 在 1980 年代某个时候的样子。
然后有一些我不确定的历史混淆:我记得它发生但我不记得顺序。首先,在 Lisp-1 中你不需要任何 function
东西:表格 car
表示获取 cons 的 car 的函数,你不需要说 (function car)
.同样(lambda (...) ...)
表示一个函数。除此之外还有另一个提议的 Lisp 标准,它是/是 ISLisp,可能是 here .尽管 ISLisp 不是 Lisp-1,它确实有一个形式 (lambda (...) ...)
表示一个函数。
人们希望 CL 能够与 ISLisp 兼容,这意味着 (lambda (...) ...)
应该表示一个函数。每个人实际上所做的是偷偷添加一个定义,例如:
(defmacro lambda (args &body forms)
`(function (lambda ,args ,@forms)))
但是,至关重要的是,您不能在 CL 中以可移植的方式执行此操作,因为 lambda
是cl:lambda
并且您不得重新定义 CL 包中的内容。人们还是这样做了,但结果是他们的程序不可移植,而且经常不得不用特殊的魔法装饰来解锁和重新锁定CL
。包。
好吧,解决方案是语言 必须提供这样一个宏。在 CLtL1 定义的语言和最终标准之间的某个时候,这发生了,所以现在 lambda
有一个宏定义,其扩展是(或多或少:实现可能被允许做特殊的事情)明显的扩展:
(lambda (x) x)
-> #'(lambda (x) x)
所以在现代 CL 中:
lambda
表示('names')形式为 (function (lambda (...) ...)
的函数并且在表单的函数位置,所以 ((lambda (x) x) 1)
, 说。lambda
被定义为扩展为 (function (lambda (...) ...))
的宏这使得它更易于使用。注意:我认为您正在使用的实现允许执行它对宏所做的操作,但您不应该依赖于此:
It is an error to use function on a function name that does not denote a function in the lexical environment in which the function form appears. Specifically, it is an error to use function on a symbol that denotes a macro or special form. An implementation may choose not to signal this error for performance reasons, but implementations are forbidden from defining the failure to signal an error as a useful behavior. – CLHS
你真的应该使用 macro-function
它会告诉您某些东西是否有宏定义。
关于lambda - Common Lisp 中的 lambda 表达式是宏还是标记?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67642412/
可以使用 lambda 和函数创建有序对(Lisp 中的缺点),如 Use of lambda for cons/car/cdr definition in SICP 所示。 它也适用于 Python
我正在尝试从另一个调用一个 AWS lambda 并执行 lambda 链接。这样做的理由是 AWS 不提供来自同一个 S3 存储桶的多个触发器。 我创建了一个带有 s3 触发器的 lambda。第一
根据以下源代码,常规 lambda 似乎可以与扩展 lambda 互换。 fun main(args: Array) { val numbers = listOf(1, 2, 3) f
A Tutorial Introduction to the Lambda Calculus 本文介绍乘法函数 The multiplication of two numbers x and y ca
我想弄清楚如何为下面的表达式绘制语法树。首先,这究竟是如何表现的?看样子是以1和2为参数,如果n是 0,它只会返回 m . 另外,有人可以指出解析树的开始,还是一个例子?我一直找不到一个。 最佳答案
在 C++0x 中,我想知道 lambda 函数的类型是什么。具体来说: #include type1 foo(int x){ return [x](int y)->int{return x * y
我在其中一个职位发布中看到了这个问题,它询问什么是 lambda 函数以及它与高阶函数的关系。我已经知道如何使用 lambda 函数,但不太自信地解释它,所以我做了一点谷歌搜索,发现了这个:What
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
Evaluate (((lambda(x y) (lambda (x) (* x y))) 5 6) 10) in Scheme. 我不知道实际上该怎么做! ((lambda (x y) (+ x x
我正在处理 MyCustomType 的实例集合如下: fun runAll(vararg commands: MyCustomType){ commands.forEach { it.myM
Brian 在他对问题 "Are side effects a good thing?" 的论证中的前提很有趣: computers are von-Neumann machines that are
在 Common Lisp 中,如果我希望两个函数共享状态,我将按如下方式执行 let over lambda: (let ((state 1)) (defun inc-state () (in
Evaluate (((lambda(x y) (lambda (x) (* x y))) 5 6) 10) in Scheme. 我不知道实际上该怎么做! ((lambda (x y) (+ x x
作为lambda calculus wiki说: There are several possible ways to define the natural numbers in lambda cal
我有一个数据类,我需要初始化一些 List .我需要获取 JsonArray 的值(我使用的是 Gson)。 我做了这个函数: private fun arrayToList(data: JsonAr
((lambda () )) 的方案中是否有简写 例如,代替 ((lambda () (define x 1) (display x))) 我希望能够做类似的事情 (empty-lam
我在 Java library 中有以下方法: public void setColumnComparator(final int columnIndex, final Comparator colu
我正在研究一个函数来计算国际象棋游戏中棋子的有效移动。 white-pawn-move 函数有效。当我试图将其概括为任一玩家的棋子 (pawn-move) 时,我遇到了非法函数调用。我已经在 repl
考虑这段代码(在 GCC 和 MSVC 上编译): int main() { auto foo = [](auto p){ typedef decltype(p) p_t;
我正在阅读一个在 lambda 内部使用 lambda 的片段,然后我想通过创建一个虚拟函数来测试它,该函数从文件中读取然后返回最大和最小数字。 这是我想出来的 dummy = lambda path
我是一名优秀的程序员,十分优秀!