- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我希望有人能解释为什么测试 1-5 有效而测试 6 无效。我认为用 ' 引用 lambda 并在 lambda 前面使用 #' 都会返回指向函数的指针,唯一的区别是 #' 将首先编译它。
(defun test-1 (y)
(mapcar (lambda (x) (expt x 2))
'(1 2 3)))
(defun test-2 (y)
(mapcar (lambda (x) (expt x y))
'(1 2 3)))
(defun test-3 (y)
(mapcar #'(lambda (x) (expt x 2))
'(1 2 3)))
(defun test-4 (y)
(mapcar #'(lambda (x) (expt x y))
'(1 2 3)))
(defun test-5 (y)
(mapcar '(lambda (x) (expt x 2))
'(1 2 3)))
(defun test-6 (y)
(mapcar '(lambda (x) (expt x y))
'(1 2 3)))
我使用的是免费版的 Franz Industries Allegro Common Lisp。以下是输出:
(test-1 2) ; --> (1 4 9)
(test-2 2) ; --> (1 4 9)
(test-3 2) ; --> (1 4 9)
(test-4 2) ; --> (1 4 9)
(test-5 2) ; --> (1 4 9)
(test-6 2) ; --> Error: Attempt to take the value of the unbound variable `Y'. [condition type: UNBOUND-VARIABLE]
最佳答案
首先,您应该知道您的测试 1-4 符合 Common Lisp,而您的测试 5 和 6 不符合。我相信 Allegro 完全可以做它为 5 和 6 做的事情,但它所做的超出了标准。标准中谈到这一点的是像 mapcar
这样的函数的定义。 , 以函数指示符 作为参数,以及 function designator 的定义:
function designator n. a designator for a function; that is, an object that denotes a function and that is one of: a symbol (denoting the function named by that symbol in the global environment), or a function (denoting itself). The consequences are undefined if a symbol is used as a function designator but it does not have a global definition as a function, or it has a global definition as a macro or a special form. [...]
从这里可以清楚地看出,像 (lambda (...) ...)
这样的列表不是函数指示符:它只是一个列表,其汽车恰好是 lambda
. Allegro 正在做的是注意到这个列表实际上是可以转化为函数的东西,并这样做。
好吧,让我们写一个版本的mapcar
Allegro 的功能:
(defun mapcar/coercing (maybe-f &rest lists)
(apply #'mapcar (coerce maybe-f 'function) lists))
这只使用 coerce
这是一个知道如何将这样的列表转换为函数的函数。如果它的参数已经是一个函数,coerce
只是返回它。
现在我们可以使用这个函数编写两个测试:
(defun test-5/coercing (y)
(mapcar/coercing '(lambda (x) (expt x 2))
'(1 2 3)))
(defun test-6/coercing (y)
(mapcar/coercing '(lambda (x) (expt x y))
'(1 2 3)))
那么,在序言之后,为什么不能 test-6/explicit
工作?好吧,答案是 Common Lisp 是(特殊变量除外)词法作用域。 词法作用域 只是一种奇特的说法,表示可用的绑定(bind)(变量)完全是并且只有您可以通过查看程序源代码看到 的绑定(bind)。 (除了用于特殊绑定(bind)的 CL,我将忽略它,因为这里没有。)
因此,考虑到这一点,考虑 test-6/coercing
,特别是对 mapcar/coercing
的调用:在那次通话中,coerce
不得不翻榜(lambda (x) (expt z y))
成一个函数。所以它就是这样做的。但它返回的函数不绑定(bind) y
y
没有绑定(bind)其中可见:函数使用 y
“免费”。
唯一可行的方法是 coerce
的函数我们的构造是动态寻找y
的绑定(bind).好吧,这就是动态范围语言所做的,但 CL 不是动态范围的。
也许使这一点更清楚的一种方法是认识到我们可以直接从函数中提取函数创建:
(defun test-7 (y f)
(mapcar f '(1 2 3)))
> (test-7 1 (coerce '(lambda (x) (expt x y)) 'function))
很明显,这在词法范围的语言中是行不通的。
那么,测试 1-4 是如何工作的?
嗯,首先这里实际上只有两个测试。在 CL 中,lambda
是一个宏并且(lambda (...) ...)
完全等同于(function (lambda (...) ...))
.当然还有#'(lambda (...) ...)
也与(function (lambda (...) ...))
相同: 它只是一个读取宏。
和(function ...)
是一个神奇的东西(一种特殊形式),它说“这是一个函数”。关于 function
的重要事项是它不是一个函数:它是一个非常神奇的东西,它告诉计算器(或编译器)它的参数是函数的描述在当前词法上下文中,所以,例如在 p>
(let ((x 1))
(function (lambda (y) (+ x y))))
x
此创建的函数引用的是 x
受约束 let
.所以在你的测试 2 和 4(它们是相同的)中:
(defun test-4 (y)
(mapcar (function (lambda (x) (expt x y)))
'(1 2 3)))
y
的绑定(bind)创建的函数引用的是 y
的绑定(bind)这是词汇可见的,这是 test-4
的参数本身。
关于lisp - Lisp(Allegro Common Lisp)如何在 ' vs #' 的 lambda 中使用变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64308742/
可以使用 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
我是一名优秀的程序员,十分优秀!