【问题标题】:Resolving symbols in a Common Lisp list解析 Common Lisp 列表中的符号
【发布时间】: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 中计算值的原始操作称为求值。

标签: lisp common-lisp symbols evaluation


【解决方案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 - 我通常使用引号来避免列表应用。我不知道我有什么特别的原因。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-25
    • 1970-01-01
    • 2012-04-02
    • 1970-01-01
    • 2013-05-16
    相关资源
    最近更新 更多