阅读 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/