Lisp listp的意外结果

Lisp listp的意外结果,lisp,common-lisp,predicate,Lisp,Common Lisp,Predicate,我有一个结构蜘蛛: (defstruct spider omegas values k) 还有一个实例蜘蛛: 但当我在Emacs和SBCL上运行表达式:listp car spider-k*spider*时,涉及到SLIME,但我不确定它是什么。 REPL返回T。这显然令人困惑,因为car spider-k*spider*正确返回“OMEGASHIFT”,而listp函数OMEGASHIFT正确返回零 为什么listp car spider-k*spider*是真的?omegashift是一个

我有一个结构蜘蛛:

(defstruct spider omegas values k)
还有一个实例蜘蛛:

但当我在Emacs和SBCL上运行表达式:listp car spider-k*spider*时,涉及到SLIME,但我不确定它是什么。 REPL返回T。这显然令人困惑,因为car spider-k*spider*正确返回“OMEGASHIFT”,而listp函数OMEGASHIFT正确返回零

为什么listp car spider-k*spider*是真的?omegashift是一个读卡器宏,可扩展为列表函数omegashift

当您计算omegashift函数时,您会得到一个函数,但您没有计算它,因为您引用了列表。因此,您只需要获取reader宏扩展到的列表

如果你做了listp car foo,你也会看到同样的事情。”foo展开为引用foo的列表。这将计算为符号foo,但列表前的引号会阻止计算

要获取函数而不是列表,需要对函数表达式求值。您可以通过调用函数列表而不是引用列表来实现这一点

(setq *spider* (make-spider
  :omegas '()
  :values (list *input*)
  :k (list #'omegashift #'dec #'dupval (list (cons 0  #'dec) (cons 1  #'inc) (cons 2  #'dec)))))
您还可以使用反报价简化此操作:

(setq *spider* (make-spider
  :omegas '()
  :values (list *input*)
  :k `(,#'omegashift ,#'dec ,#'dupval '((0 . ,#'dec) (1 . ,#'inc) (2 . ,#'dec)))))
在反引号表达式中,使用逗号标记要计算的子表达式

顺便说一句,您应该使用setq来分配变量,而不是用引号来设置。它们对于全局变量是等效的,但不能将set与局部变量一起使用。

'omegashift是一个读卡器宏,可扩展为列表函数omegashift

当您计算omegashift函数时,您会得到一个函数,但您没有计算它,因为您引用了列表。因此,您只需要获取reader宏扩展到的列表

如果你做了listp car foo,你也会看到同样的事情。”foo展开为引用foo的列表。这将计算为符号foo,但列表前的引号会阻止计算

要获取函数而不是列表,需要对函数表达式求值。您可以通过调用函数列表而不是引用列表来实现这一点

(setq *spider* (make-spider
  :omegas '()
  :values (list *input*)
  :k (list #'omegashift #'dec #'dupval (list (cons 0  #'dec) (cons 1  #'inc) (cons 2  #'dec)))))
您还可以使用反报价简化此操作:

(setq *spider* (make-spider
  :omegas '()
  :values (list *input*)
  :k `(,#'omegashift ,#'dec ,#'dupval '((0 . ,#'dec) (1 . ,#'inc) (2 . ,#'dec)))))
在反引号表达式中,使用逗号标记要计算的子表达式


顺便说一句,您应该使用setq来分配变量,而不是用引号来设置。它们对于全局变量是等价的,但不能将set与局部变量一起使用。

我没有使用setq,因为当我使用SBCL时,会抱怨未定义的变量使用defvar声明全局变量,那么它不会抱怨。我没有使用setq,因为当我使用SBCL时,会抱怨未定义的变量使用defvar声明全局变量,那么它不会抱怨。