Scheme中引用的符号

时间:2011-07-11 13:06:51

标签: clojure 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?)有条件的,但这可能是错误的方法。

我正在使用Chicken Scheme。

1 个答案:

答案 0 :(得分:18)

你遇到了Lisp引用“gotcha”。在Scheme中,符号用于变量引用,您显然可以理解。评估为true:

> (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等同于(引用Symb),这实际上是一个列表。由于引用了整个列表,因此使用Symb未引用不会被视为变量引用。它只是符号。

> (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))

会做同样的事情。