Scheme - 未绑定变量:unquote

ske*_*rus 3 recursion scheme

我是Scheme的新手; 我正在编写一个程序,以重复添加的方式递归地定义乘法:

(define multiply 
  (lambda (a b) 
    (if (= b 0) 
        0 
        (+ a (multiply(a, (- b 1)))))))
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试运行该程序时,我收到错误消息:

;Unbound variable: unquote
Run Code Online (Sandbox Code Playgroud)

什么是错误信息,我该如何纠正?

Syl*_*ter 6

既然你熟悉algol家族语言(python),我可以告诉你lisp系列有不同的语法:

fun(a, b, c)
Run Code Online (Sandbox Code Playgroud)

写得像这样:

(fun a b c)
Run Code Online (Sandbox Code Playgroud)

因此,错误的来源是在lisp语言中逗号和括号的解释不同.

引用的错误消息是什么? 在lisp系列中,您实际上可以通过添加使代码文字成为字符的字符来将代码作为数据.所以在评估之后'(fun a b c)变成(fun a b c)一个数据结构,因为你有一个'在它前面,它的工作就像你 code(a,b,c)在python中并用引号包围它一样'code(a,b,c)'.Python会把它评估为字符串而不是代码吗?好的lisp语言对文字数据结构也是如此.还有2个.quasiquote `unquote ,.看起来熟悉不是吗?正如同化一样,法线quote就像单引号字符串,其中字符串完全是字面的,而quasiquote像双引号字符串,而unquote用于代码的插值,因此结构中剩余的是这些表达式的结果.这是一个例子:

`(a b ,(+ 3 4)))
; ==> (a b 7)
Run Code Online (Sandbox Code Playgroud)

现在,在LISP语言的读者通常在读取时间将这个,使得被解释的代码永远不会真正看到',`,.Scheme标准没有说它应该命名的是什么,所以它的实现是定义的,但是大多数语言都使用这些:

''`(a b ,(+ 3 4))
; ==> (quote (quasiquote (a b (unquote (+ 3 4)))))
Run Code Online (Sandbox Code Playgroud)

仅评估最外层引用,因此在这种情况下,您在结果中看到的其他引号是数据而不是代码的一部分.在呈现数据结构时,实现可以自由显示简短形式,以便:

'(quote (unquote quote))
; ==> ',quote 
; ==> (quote (unquote quote))
Run Code Online (Sandbox Code Playgroud)

它实际上是相同的值,但它们如何显示它是一种变化,如果你要采用car它会呈现符号,quote因为它确实是第二个结构是真正的价值.

在您的代码中,表达式在成功减法后(a, (- b 1))读入(a (unqote (- b 1)))函数unquote,然后将函数a应用于它的结果.两者都不会起作用,但由于必须在应用程序之前评估参数,因此设置顺序,因此Scheme会unquote先注意,然后a稍后如果要删除逗号.