clojure - Scheme中引用的符号

标签 clojure scheme

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

我正在使用鸡肉计划。

最佳答案

你遇到了 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))

引用了整个列表;列表中的任何内容都不会被评估。这就是为什么
> tree ; => (1 2 3 (quote Symb) 4 5 6)

在引用列表内部,'Symb 相当于 (quote 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))

会做同样的事情。

关于clojure - Scheme中引用的符号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6650536/

相关文章:

functional-programming - 如何判断变量的值是否是绑定(bind)到 Scheme 中的过程的符号?

scheme - Common Lisp 中的延续传递风格?

方案:似乎无法加载文件

lisp - 实现同时绑定(bind)

performance - 为什么 Racket 的实现比 MIT Scheme 快这么多?

clojure - 在 clojure 中将映射列表减少为列表

clojure:with-redefs 不适用于 clojure.core 函数?

Clojure - 为什么 into 对列表的行为不同于对向量的行为?

clojure - Lein 检查 : case has int tests, 但测试的表达式不是原始的

Clojureql - 无法获取宏的值(clojure)