- 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/
如何在 Excel 中编写可以在我将打开的任何 Excel 文档上工作(使用快捷方式运行)的宏? 这可能吗? 最佳答案 您需要将宏添加到 Personal.xlsb 以使它们可用于所有 excel 文
我正在研究 problem #74在4clojure.com,我的解决方案如下: (defn FPS [s] (->> (map read-string (re-seq #"[0-9]+"
我还没有完全理解Clojure 箭头宏thread-first -> 和thread-last 宏->> 之间的区别。在阅读 https://clojure.org/guides/threading_
我想将一些调试输出语句插入到大型 C 代码库中。这些调试输出语句将由编译器选项开关控制。 调试输出语句如下所示: #ifdef DEBUG_FLAG Print(someSymbol) #endif
我正在通过宏将代码注入(inject)到 C++ 类中。有没有办法根据访问修饰符的上下文来做到这一点?有点像 #if (we_are_in_public_context) INJECT_PUBLIC_
这应该与 memoize 类似,但有很大不同。虽然 memoize 应该与纯函数一起使用,但它通常对加速 IO 相关函数很有用。 我正在寻找的函数/宏应该表现得像高阶函数。它产生的功能应该: 第一次调
对于下面的代码: let services: [MyServices] = [ MyService(), #if DEBUG DebugService(), #endi
假设我有以下文本文件 name: John Doe description: My name is John Doe and I'm really good at vim! name: John Do
在创建 Excel 宏方面需要帮助。我有一个 Excel 工作表。Excel 工作表不一致。我打算使它统一和结构化。 例如。 A B C
我正在 excel 中设置一个宏,以便在更新单元格时自动发送电子邮件。是否可以在电子邮件正文中包含单元格的内容?例如,如果单元格 G7 已更新,请在电子邮件中包含单元格 B7 的内容?单元格行将是相同
我创建了一个简单的 Excel 工作表。 这是我的宏代码: Sub MyMacro() Sheets("Sheet1").Select A$ = Cells(1, 1) Msg
在 Excel 的 VB 宏中,如何删除所有出现的以某个字符串开头的单词? 例如: 字符串内容为:xxxx $AUD543.43 yyyy 我想搜索以 $AUD 开头的字符串中的任何内容并删除下一个空
我是 Excel 宏的新手.. 谁能告诉我这个宏是做什么的? Sub People_Add_Document() prow = ActiveCell.row num = Cells(p
我对 Excel 中的 VBA 和宏非常陌生。我有一个非常大的 Excel 电子表格,其中 A 列保存日期。我正在尝试删除值小于某个日期的行,这就是我到现在为止的想法。 Sub DELETEDATE(
我在 Excel 2003 中有一个 VBA 对象,当通过流数据获得某些值时,它会触发三个简单的宏。它运行良好。我想打开一个重复的工作表,但具有不同的流数据,并在各自的工作表上触发宏。它现在可以使用,
下面的宏有什么问题?我只想评估一个选项卡中的一个单元格是否大于另一个选项卡中的另一个单元格。然后消息框: Sub Comhouse() If Worksheets("(2.2) TRA works
需要一个简单的 excel 宏的帮助。我在第 1 列 X1 到 X20 中有数据。我想自动将此信息粘贴到 A 列,然后当我更新 X 列中的数字时,我想将此信息粘贴到 B 列,然后再粘贴到 C 列...
我找到了以下代码,效果很好;但是,我必须手动更改月份,以便它转到第二个工作簿的右侧工作表。由于工作表以月为单位,我怎样才能使其自动更改为当月? Sub AlarmSheet() Dim wkb As
很难说出这里问的是什么。这个问题是模棱两可的、模糊的、不完整的、过于宽泛的或修辞的,无法以目前的形式得到合理的回答。如需帮助澄清这个问题以便重新打开它,visit the help center .
我的公司只使用 MS Office 2003 产品,所以我必须坚持下去。由于我的工作性质,我需要使用很多“复制和粘贴”功能。源数据主要来自网站,我将数据粘贴到 Excel 中的单元格中。问题是剪贴板保
我是一名优秀的程序员,十分优秀!