我是Scheme的新手;我正在编写一个程序,用递归方式定义乘法:
(define multiply
(lambda (a b)
(if (= b 0)
0
(+ a (multiply(a, (- b 1)))))))
但是,当我尝试运行程序时,我收到错误消息:
;Unbound variable: unquote
引用的错误信息是什么,我该如何纠正?
答案 0 :(得分:6)
由于你熟悉algol家族语言(python),我可以告诉你lisp系列有不同的语法:
fun(a, b, c)
写得像这样:
(fun a b c)
因此,您的错误来源是在lisp语言中解释逗号和括号不同。
引用的错误消息是什么?
在lisp系列中,您实际上可以通过添加使代码文字成为字符的字符来将代码作为数据。因此,'(fun a b c)
在评估后变为(fun a b c)
作为数据结构,因为前面有一个'
,就像你在python中有code(a,b,c)
并用引号包围它一样比如'code(a,b,c)'
。 Python会把它评估为字符串而不是代码吗?好的lisp语言对文字数据结构也是如此。还有2个。 quasiquote
`
和unquote
,
。看起来熟悉不是吗?正如同化一样,正常quote
就像单引号字符串,其中字符串完全是字面的,而quasiquote
就像双引号字符串,而unquote用于代码的插值,以便结构中剩余的是这些表达的结果。这是一个例子:
`(a b ,(+ 3 4)))
; ==> (a b 7)
现在,在lisp语言中,读者通常会在读取时对其进行转换,以便解释的代码实际上看不到'
,`
或,
。 Scheme标准没有说它应该命名的是什么,所以它的实现是定义的,但大多数语言使用这些:
''`(a b ,(+ 3 4))
; ==> (quote (quasiquote (a b (unquote (+ 3 4)))))
仅评估最外层引用,因此在这种情况下,您在结果中看到的其他引号是数据而不是代码的一部分。在呈现数据结构时,实现可以自由地显示简短形式,以便:
'(quote (unquote quote))
; ==> ',quote
; ==> (quote (unquote quote))
它实际上是相同的值,但它们如何显示它是一种变体,如果你要使用car
它会呈现符号quote
,因为它确实是第二个结构是真正的价值。
在您的代码中,表达式(a, (- b 1))
作为(a (unqote (- b 1)))
读入,成功减法后,将应用函数unquote
,然后函数a
将是适用于它的结果。两者都不会起作用,但由于必须在申请之前评估参数,因此设置顺序,因此Scheme会首先投诉unquote
,然后如果您删除逗号则会a
。
答案 1 :(得分:3)
除了上面完全正确的答案之外:当您学习编程时,最重要的技能之一是学习如何通过删除程序中可删除的部分而不更改错误来隔离错误,以达到显示错误的最小可能程序。从长远来看,这将为您节省大量时间!
答案 2 :(得分:1)
Scheme使用空格来分隔参数,而不是逗号(错误消息中提到的unquote
运算符)。