我不是计划专家所以不确定我是否在这里使用正确的术语.让代码说明一切:
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)
会做同样的事情.