【问题标题】:Symbols quoted in SchemeScheme中引用的符号
【发布时间】:2023-03-18 08:40:02
【问题描述】:

我不是 Scheme 专家,所以不确定我是否在这里使用了正确的术语。让代码自己说话:

CSI> (define tree '(1 2 3 'Symb 4 5 6))
#<unspecified>
CSI> tree
(1 2 3 (quote Symb) 4 5 6)
CSI> (symbol? 'Symb)
#t
CSI> (map symbol? tree)
(#f #f #f #f #f #f #f)

来自 Clojure 背景,我认为符号在 Scheme 中是这样使用的,就像 Clojure 中的关键字一样。我应该通过嵌套列表结构并用函数调用替换符号。这是我的一维解决方案,它确实有效:

(define (print-track track attrs)
    (apply fmt #t
        (map (lambda (attr)
               (cond 
                     ((symbol? attr) (get-attr attr track))
                     (else           attr)))
             attrs)))

(symbol?) 行上方的空白区域用于(list?) 条件,但这可能是错误的方法。

我正在使用鸡计划。

【问题讨论】:

    标签: clojure scheme


    【解决方案1】:

    您遇到了 Lisp 引用“gotcha”。在 Scheme 中,符号用于变量引用,这一点您显然明白。这评估为真:

    > (symbol? 'Symb)
    

    因为您引用了该符号,并阻止它被用作变量引用。

    > (symbol? Symb)
    

    首先查找 Symb 变量的值,然后检查该值是否为符号。

    > (let ((Symb 'foo)) (symbol? Symb))
    

    计算结果为#t,因为 Symb 的值是一个符号:foo。

    > (let ((Symb 7)) (symbol? Symb))
    

    当然会计算为#f。

    您似乎被引语的细微差别绊倒了。

    'Symb
    

    实际上是简写;相当于

    (quote Symbol)
    

    它再次返回其未评估的参数。

    但是您的代码不需要内引号。当你

    > (define tree '(1 2 3 'Symb 4 5 6))
    

    整个列表都被引用了;列表中的 nothing 将被评估。这就是为什么

    > tree ; => (1 2 3 (quote Symb) 4 5 6)
    

    在引用列表里面,'Symb等价于(quote Symb),其实就是一个列表。由于引用了整个列表,因此使用 Symb unquoted 不会被视为变量引用。它只是一个符号。

    > (define tree '(1 2 3 Symb 4 5 6))
    > tree ; => (1 2 3 Symb 4 5 6)
    

    现在,如果您将所有这些参数传递给 list 函数,那么您最初所做的将是正确的:

    > (define tree (list 1 2 3 'Symb 4 5 6))
    > tree ; => (1 2 3 Symb 4 5 6)
    

    在这种情况下,您将这些参数传递给函数;对函数的参数进行评估,因此您需要使用引号来防止符号被视为变量引用。

    > (define tree (list 1 2 3 (quote Symb) 4 5 6))
    

    会做同样的事情。

    【讨论】:

      猜你喜欢
      • 2023-03-27
      • 2020-06-26
      • 1970-01-01
      • 1970-01-01
      • 2014-03-23
      • 1970-01-01
      • 1970-01-01
      • 2013-06-28
      • 2013-05-28
      相关资源
      最近更新 更多