Ste*_*rus 1 lisp predicate common-lisp
我有一个结构蜘蛛:
(defstruct spider omegas values k)
Run Code Online (Sandbox Code Playgroud)
和一个实例蜘蛛:
(set '*spider* (make-spider
:omegas '()
:values (list *input*)
:k '(#'omegashift #'dec #'dupval '((0 . #'dec) (1 . #'inc) (2 . #'dec)))))
Run Code Online (Sandbox Code Playgroud)
但是当我运行表达式时:(listp (car (spider-k *spider*))在 Emacs 和 SBCL 上(并且涉及 SLIME,但我不确定它是什么。)REPL 返回T. 这显然令人困惑,因为(car (spider-k *spider*)正确返回#'OMEGASHIFT和(listp (function OMEGASHIFT))正确返回NIL。
为什么是(listp (car (spider-k *spider*))真的?不应该是假的吗?
#'omegashift是一个扩展到 list 的读取器宏(function omegashift)。
当您评估时,(function omegashift)您会得到一个函数,但您并未评估它,因为您引用了列表。所以你只是得到了读取器宏扩展到的列表。
如果你这样做,你会看到同样的事情(listp (car '('foo)))。'foo扩展到列表(quote foo)。这计算为符号foo,但列表前的引号阻止计算。
要获取函数而不是列表,您需要计算函数表达式。您可以通过调用函数list而不是引用列表来做到这一点。
(setq *spider* (make-spider
:omegas '()
:values (list *input*)
:k (list #'omegashift #'dec #'dupval (list (cons 0 #'dec) (cons 1 #'inc) (cons 2 #'dec)))))
Run Code Online (Sandbox Code Playgroud)
您还可以使用反引号来简化此操作:
(setq *spider* (make-spider
:omegas '()
:values (list *input*)
:k `(,#'omegashift ,#'dec ,#'dupval '((0 . ,#'dec) (1 . ,#'inc) (2 . ,#'dec)))))
Run Code Online (Sandbox Code Playgroud)
在反引号表达式中,您使用逗号来标记要计算的子表达式。
顺便说一句,您应该使用setq分配变量,而不是set使用带引号的符号。它们对于全局变量是等价的,但不能set与局部变量一起使用。