解析 Common Lisp 列表中的符号

Posted

技术标签:

【中文标题】解析 Common Lisp 列表中的符号【英文标题】:Resolving symbols in a Common Lisp list 【发布时间】:2011-05-12 04:20:05 【问题描述】:

假设我有一个函数

CL-USER> (defun trimmer (seq) "This trims seq and returns a list"
      (cdr 
         (butlast seq)))
TRIMMER
CL-USER> (trimmer '(1 2 3 VAR1 VAR2))
(2 3 VAR1)
CL-USER> 

请注意,由于 QUOTE,VAR1 和 VAR2 无法解析。假设我想将符号 VAR1 和 VAR2 解析为它们的值 - 是否有标准函数可以做到这一点?

【问题讨论】:

使用list而不是quote有什么问题? 在 Lisp 上下文中“解决”是什么意思? Lisp 中计算值的原始操作称为求值。 【参考方案1】:

不要使用quote 来创建带有变量的列表;改用list

CL-USER> (trimmer (list 1 2 3 var1 var2))
(2 3 value-of-var1)

(其中value-of-var1var1 的值)。

Quote 只会阻止对其参数进行评估。如果它的参数恰好是一个列表文字,那么它就会被返回。但是,要创建不仅仅是文字的列表,请使用list。您可以使用反引号语法,但在这种情况下,这是相当混乱的。

【讨论】:

【参考方案2】:

Backquote 是将值插入引用列表的常用方法:

> (setq var1 4 var2 5)
5
> `(1 2 3 ,var1 ,var2)
(1 2 3 4 5)

编辑添加:如果你想处理一个列表,以便将符号替换为它们的symbol-value,那么你需要一个类似这样的函数:

(defun interpolate-symbol-values (list)
  "Return a copy of LIST with symbols replaced by their symbol-value."
  (loop for x in list
        collect (if (symbolp x) (symbol-value x) x)))

> (interpolate-variables '(1 2 3 var1 var2))
(1 2 3 4 5)

然而,这似乎是一件奇怪的事情。你能多谈谈你想要达到的目标吗?几乎可以肯定,还有比这更好的方法。

【讨论】:

我不知道列表中可能有多少个未解析的变量。 怎么回事?在您的问题描述中,您提到使用QUOTE。如果您可以使用QUOTE,您肯定可以使用反引号吗? (也许你需要更明确地描述你的问题。) @Gareth:我使用引号来确保第一个参数没有被评估为函数。 是的,但是反引号也避免了函数应用。我还不明白为什么你可以做一个但不能做另一个。 @Gareth - 我通常使用引号来避免列表应用。我不知道我有什么特别的原因。

以上是关于解析 Common Lisp 列表中的符号的主要内容,如果未能解决你的问题,请参考以下文章

替换 Common Lisp 列表中的项目?

Common Lisp:将符号传递给宏

合并常见lisp中的符号

Common-Lisp:绑定形式参数,到底传递了啥?

如何使用依赖于包装它的较短列表的 map 循环较长的列表以将某些函数应用于 Common Lisp 中的较长列表?

在 common lisp 中复制结构列表