listp的意外结果

问题描述 投票:0回答:1

我有一个结构蜘蛛:

(defstruct spider omegas values k)

和实例蜘蛛

(set '*spider* (make-spider
  :omegas '()
  :values (list *input*)
  :k '(#'omegashift #'dec #'dupval '((0 . #'dec) (1 . #'inc) (2 . #'dec)))))

但是当我在Emacs和SBCL上运行表达式:(listp (car (spider-k *spider*))时(涉及SLIME,但我不确定它是什么。)REPL返回T。显然这令人困惑,因为(car (spider-k *spider*)正确返回#'OMEGASHIFT(listp (function OMEGASHIFT))正确返回NIL

为什么(listp (car (spider-k *spider*))为真?不应该是假的吗?

lisp common-lisp predicate
1个回答
0
投票

#'omegashift是一个阅读器宏,它扩展到列表(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)))))

您还可以使用反引号简化此操作:

(setq *spider* (make-spider
  :omegas '()
  :values (list *input*)
  :k `(,#'omegashift ,#'dec ,#'dupval '((0 . ,#'dec) (1 . ,#'inc) (2 . ,#'dec)))))

在反引号内,您使用逗号标记要评估的子表达式。

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

© www.soinside.com 2019 - 2024. All rights reserved.