【问题标题】:', (quote-comma) in common lisp',(引号逗号)在普通 lisp 中
【发布时间】:2020-02-24 14:46:12
【问题描述】:

在lisp的反引号表达式中',的作用和使用是什么?它有名字吗?它是否记录在某处?它有多常见和有用?

例如:

(defmacro test-exp (exp)
  `(format t "~&~S => ~S~%" ',exp ,exp))

我的猜测是,在宏扩展时,它将采用 exp 的字面意思,并用它替换 ',exp。 (而不是评估 exp 并用它替换 ,exp)。

【问题讨论】:

    标签: escaping common-lisp quoting backquote


    【解决方案1】:

    你猜对了。

    报价

    特殊运算符quote 定义了一个表达式,该表达式计算为它的子形式,字面意思。例如:

    (quote (looks like a function call))
    

    内部形式看起来像一个函数调用,但对于 Lisp 阅读器来说,这只是一个符号列表。表达式(quote ...) 计算为该列表,而不尝试将该列表作为代码进行计算。

    引用表达式有特殊语法,即引号字符,因此'exp(quote exp) 相同。当您不想评估符号时,这通常是您编写符号的方式。

    反引号/逗号

    准引用是一种只引用表达式的一部分的方法。

    反引号的作用类似于引号:不评估其中的数据,除非它们以逗号为前缀,在这种情况下,评估会重新打开。 下面的表达式

    `(format t "~s" ,exp)
    

    ...可以写成:

    (list 'format 't '"~s" exp)
    

    为了完整起见,我在文字之前添加了引号,否则会自我评估,但实际上您会编写如下相同的列表:

    (list 'format t "~s" exp)
    

    这里exp 被求值,整个表单给出了一个类似于对format 的调用的列表,其中env 被替换为其值。

    引用逗号

    您在示例中看到的引号/逗号组合是一个常见的习惯用法,您希望将在宏扩展时(即代码)给出的参数按字面意思放在正在扩展的代码中,而不对其进行评估。如果你通过宏扩展来测试你的宏,你可以看到生成的代码:

    (macroexpand '(test-exp (+ 5 8)))
    
    => (FORMAT T "~&~S => ~S~%" '(+ 5 8) (+ 5 8))
    

    文字 (+ 5 8) 表单被放置在 (quote ...) 表单中,使其在运行时未计算。同时,相同的表达式按原样放在它旁边,从而在运行时对其进行评估。如果您评估结果表达式,它会打印:

     (+ 5 8) => 13
    

    【讨论】:

    • ',exp 本质上是(quote (unquote exp))。我知道unquote 仅在quasiquote 中才有意义。我怀疑',expexp 不同,只有quoteunquote 在编译时运行。我对吗?它们的功能也可以不同吗?
    【解决方案2】:

    ', 只能用于反引号表达式。它们是两个不同的读取器宏 ' 用于引用和 , 用于在反引号 s 表达式中进行评估。逗号只能出现在反引号表达式中。

    `(a ',(+ 1 2))
    

    以上同

    `(a (QUOTE ,(+ 1 2)))
    

    因为'quote 的阅读器宏。

    因此它具有类似的效果:

    (list (quote a) (list (quote quote) (+ 1 2)))
    

    计算结果为

    (A (QUOTE 3))
    

    比较

    `(a ',(+ 1 2))
    

    评估结果

    (A (QUOTE 3))
    

    它基本上引用(+ 1 2)的评估结果并将其包含在列表中。

    【讨论】:

      猜你喜欢
      • 2011-11-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-28
      • 1970-01-01
      • 1970-01-01
      • 2013-04-02
      • 1970-01-01
      相关资源
      最近更新 更多