Scheme中引用的符号

unp*_*680 7 scheme clojure

我不是计划专家所以不确定我是否在这里使用正确的术语.让代码说明一切:

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)
Run Code Online (Sandbox Code Playgroud)

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

(define (print-track track attrs)
    (apply fmt #t
        (map (lambda (attr)
               (cond 
                     ((symbol? attr) (get-attr attr track))
                     (else           attr)))
             attrs)))
Run Code Online (Sandbox Code Playgroud)

(symbol?)线上方的空白区域是(list?)有条件的,但这可能是错误的方法.

我正在使用Chicken Scheme.

Dan*_*ton 19

你已经遇到了Lisp引用"gotcha".在Scheme中,符号用于变量引用,您显然可以理解.评估结果为true:

> (symbol? 'Symb)
Run Code Online (Sandbox Code Playgroud)

因为你引用了符号,并阻止它被用作变量引用.

> (symbol? Symb)
Run Code Online (Sandbox Code Playgroud)

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

> (let ((Symb 'foo)) (symbol? Symb))
Run Code Online (Sandbox Code Playgroud)

将评估为#t,因为Symb的值是一个符号:foo.

> (let ((Symb 7)) (symbol? Symb))
Run Code Online (Sandbox Code Playgroud)

当然,会评估为#f.

你似乎惹恼了引用的细微差别.

'Symb
Run Code Online (Sandbox Code Playgroud)

实际上是速记; 它相当于

(quote Symbol)
Run Code Online (Sandbox Code Playgroud)

再次,它返回其未评估的论点.

但是你的代码不需要内部引用.当你

> (define tree '(1 2 3 'Symb 4 5 6))
Run Code Online (Sandbox Code Playgroud)

引用整个列表; 没有列表的内部要进行评估.这就是为什么

> tree ; => (1 2 3 (quote Symb) 4 5 6)
Run Code Online (Sandbox Code Playgroud)

在引用列表中,'Symb等同于(引用Symb),这实际上是一个列表.由于引用了整个列表,因此使用Symb未引用不会被视为变量引用.它只是象征.

> (define tree '(1 2 3 Symb 4 5 6))
> tree ; => (1 2 3 Symb 4 5 6)
Run Code Online (Sandbox Code Playgroud)

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

> (define tree (list 1 2 3 'Symb 4 5 6))
> tree ; => (1 2 3 Symb 4 5 6)
Run Code Online (Sandbox Code Playgroud)

在这种情况下,您将这些参数传递给函数; 函数的参数被计算,因此您需要引用以防止符号被视为变量引用.

> (define tree (list 1 2 3 (quote Symb) 4 5 6))
Run Code Online (Sandbox Code Playgroud)

会做同样的事情.