#'函数名称
,这个必要吗?#在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 的值。(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函数。