6.1 全局函数 (Global Functions)
谓词 fboundp
告诉我们,是否有个函数的名字与给定的符号绑定。如果一个符号是函数的名字,则 symbol-function
会返回它:
> (fboundp '+)
T
> (symbol-function '+)
#<Compiled-function + 17BA4E>
可通过 symbol-function
给函数配置某个名字:
(setf (symbol-function 'add2)
#'(lambda (x) (+ x 2)))
新的全局函数可以这样定义,用起来和 defun
所定义的函数一样:
> (add2 1)
3
实际上 defun
做了稍微多的工作,将某些像是
(defun add2 (x) (+ x 2))
翻译成上述的 setf
表达式。使用 defun
让程序看起来更美观,并或多或少帮助了编译器,但严格来说,没有 defun
也能写程序。
通过把 defun
的第一个实参变成这种形式的列表 (setf f)
,你定义了当 setf
第一个实参是 f
的函数调用时,所会发生的事情。下面这对函数把 primo
定义成 car
的同义词:
(defun primo (lst) (car lst))
(defun (setf primo) (val lst)
(setf (car lst) val))
在函数名是这种形式 (setf f)
的函数定义中,第一个实参代表新的数值,而剩余的实参代表了传给 f
的参数。
现在任何 primo
的 setf
,会是上面后者的函数调用:
> (let ((x (list 'a 'b 'c)))
(setf (primo x) 480)
x)
(480 b c)
不需要为了定义 (setf primo)
而定义 primo
,但这样的定义通常是成对的。
由于字符串是 Lisp 表达式,没有理由它们不能出现在代码的主体。字符串本身是没有副作用的,除非它是最后一个表达式,否则不会造成任何差别。如果让字符串成为 defun
定义的函数主体的第一个表达式,
(defun foo (x)
"Implements an enhanced paradigm of diversity"
x)
那么这个字符串会变成函数的文档字符串(documentation string)。要取得函数的文档字符串,可以通过调用 documentation
来取得:
> (documentation 'foo 'function)
"Implements an enhanced paradigm of diversity"
当前内容版权归 readthedocs 或其关联方所有,如需对内容或内容相关联开源项目进行关注与资助,请访问 readthedocs .