gpt4 book ai didi

lisp - 使用# a.k.a. 读取宏

转载 作者:太空宇宙 更新时间:2023-11-03 18:44:02 25 4
gpt4 key购买 nike

阅读 Doug Hoyte 的书“Let Over Lambda”,我发现了以下对 #. 符号的描述,也就是 read-macro:

A basic read macro that comes built in with COMMON LISP is the #. read-time eval macro. This read macro lets you embed objects into the forms you read that can't be serialised, but can be created with a bit of lisp code.

它来自第 4 章,本书的大部分内容可以在这里找到: http://letoverlambda.com/index.cl/toc

这是书中的一个例子,展示了同一个表达式每次读起来可能有何不同:

* '(football-game
(game-started-at
#.(get-internal-real-time))
(coin-flip
#.(if (zerop (random 2)) 'heads 'tails)))

(FOOTBALL-GAME
(GAME-STARTED-AT 187)
(COIN-FLIP HEADS))

* '(football-game
(game-started-at
#.(get-internal-real-time))
(coin-flip
#.(if (zerop (random 2)) 'heads 'tails)))

(FOOTBALL-GAME
(GAME-STARTED-AT 309)
(COIN-FLIP TAILS))

接下来,作者演示了一些核心技巧,使用 # 宏创建变体。

所以,原来#'也是某种阅读宏,它通常用在表示函数名称的符号之前。但这是否有必要,他在那里的工作到底是什么?

我可以用 #' 或不用它来为高阶函数放置符号:

CL-USER> (defun test nil t)
TEST
CL-USER> (funcall #'test)
T
CL-USER> (funcall 'test)
T

同样成功。

最佳答案

您可以通过两种方式调用函数的全局定义:

CL-USER> (defun test nil t)
TEST
CL-USER> (funcall #'test)
T
CL-USER> (funcall 'test)
T

但是看到这个:

CL-USER 10 > (defun foo () 42)
FOO

CL-USER 11 > (flet ((foo () 82))
(print (foo))
(print (funcall 'foo))
(print (funcall #'foo)))

82 ; the local definition
42 ; the symbol references the global definition
82 ; (function foo) / #'foo references the local definition

(funcall 'foo) 从符号中查找函数。

(funcall #'foo) 从词法环境调用函数。如果没有,则使用全局定义。

#'foo(function foo) 的简写符号。

CL-USER 19 > '#'foo
(FUNCTION FOO)

关于lisp - 使用# a.k.a. 读取宏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23977617/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com