LISP中的#代表什么?

37
例如,#'函数名称,这个必要吗?
1个回答

91

#在Common Lisp中获取函数名

Common Lisp和其他一些Lisp方言有多个命名空间,其中函数和值的命名空间是不同的。要获取一个名称的函数值,我们需要编写:

(function functionname)

因为写那么长有点麻烦,所以有一个更短的符号表示:

#'functionname

为了展示效果,请查看以下内容:

(let ((foo 42))
  (flet ((foo () 'bar))
    (list foo (function foo) #'foo (foo))))
上面定义了一个本地变量 FOO 和一个本地函数 FOO。 list 语句返回 FOO 的值,然后使用 (function ...) 表示法返回 foo 的函数值,然后使用简写表示法返回相同的结果,最后返回实际调用函数 FOO 的值。
(function foo) 和 #'foo 是相同的概念,只是写法不同。两者都指代命名为 FOO 的本地词法函数。FOO 是通过 FLET 形式作为本地函数引入的。
Lisp REPL 返回类似以下内容:
(42 #<function FOO 4060008224> #<function FOO 4060008224> BAR)

上面显示了第一个项目确实是变量FOO,而接下来的两个项目是函数值,即绑定到FOO的函数。最后一项是符号BAR,从函数调用(FOO)返回。

在Common Lisp、Emacs Lisp和ISLisp中,对普通值和函数值进行命名空间的分离。其他Lisp方言如Scheme则没有这种分离方法。在Scheme中,一个名称只能表示一个值。

字符#。

字符#用于引入s表达式的特殊语法。以下是一些示例:

#'functionname   ->  (function functionname)
#(1 2 3)         ->  the vector of the elements 1 2 3
#c(1 2)          ->  a complex number
#xFFFF           ->  a hex number
#b1111           ->  a binary number

还有很多其他用途。 # 是一个所谓的“分派宏字符”。

ANSI Common Lisp HyperSpec 在第2.4.8节Sharpsign中描述了#字符。

Common Lisp 可以使用不同的语法来表示向量,比如[1 2 3];也可以使用不同的语法来表示复数,比如{1 2}。但它并没有这样做。为什么?原因是因为 Common Lisp 尝试在语言中经济使用字符,并将像[]{}这样的字符留给用户进行自己的语法扩展。通常,Lisp 用户会开发嵌入式语言,为了使这个过程更容易一些,Common Lisp标准尝试将字符使用保持到最低限度,并提供了宏字符和分派宏字符机制。

为了减少字符使用,使用单个分派字符#,然后下一个字符确定可以表示什么。比如#b代表二进制数,#x代表十六进制数,#c代表复数,#(代表向量,#'代表函数名等等。

由于 Common Lisp 是一种可编程的编程语言,用户可以更改这个字符级别的语法。请参阅SET-DISPATCH-MACRO-CHARACTER函数。


你提供了一篇很棒的文章!我恰好在需要它的时候找到了它! - TheGeeko61

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接