您好我想弄清楚如何在方案中的if语句中定义我的变量。我一直收到错误;无法在null语法环境中绑定名称:tmp ....
从我在线阅读的所有内容来看,我的语法是正确的。我不明白我是如何得到这个错误的。
这是我的代码:
(if (list? seq2)
(if (list? seq1)
(begin
(define tmp (car seq1))
(if (list? tmp)
#t
#f))
#f)
#f)
真假返回是为了测试,所以我可以看到事情的结局。
答案 0 :(得分:2)
真的,您的代码没有任何问题......我会将其问题描述为主要是历史问题。
例如,在Racket中,您的代码发出错误信号,但您可以将begin
重写为let () ...
,一切正常:
(if (list? seq2)
(if (list? seq1)
(let ()
(define tmp (car seq1))
(if (list? tmp)
#t
#f))
#f)
#f)
从历史上看,define
仅在最高级别的Scheme中被允许。诸如Racket之类的方案亲属一直在扩大允许define
的上下文集,但begin
仍然不是允许define
的上下文。
编辑:s {但begin
/ begin
if
分支/
答案 1 :(得分:1)
没有必要使用define
。您可以改用let。这是一个例子:
(if (list? seq2)
(if (list? seq1)
(let ((tmp (car seq1)))
(if (list? tmp)
#t
#f))
#f)
#f)
答案 2 :(得分:0)
存在称为and
和or
的逻辑短路语法。基本上(and expr1 expr2 expr3)
与(if expr1 (if expr2 expr3 #f) #f)
相同。我敢打赌你注意到你的代码与你的代码有相似之处,所以这里有:
(and (list? seq2)
(list? seq1)
(list? (car seq1)))
如果其中任何一个变成#f
,它将停在那里,它将是整个表格的结果。使用or
时,它会停在第一个真值(除了#f
之外的任何值)。由于它是短路的,如果(car seq1)
为(list seq1)
,它将不会尝试#f
。
变量tmp
不是必需的,但如果您需要使用let
:
(let ((tmp expression))
(if (not (null? tmp))
tmp
#f))
这当然是为了不必多次expression
。
答案 3 :(得分:0)
我使用MIT-Scheme遇到了类似的问题,并且知道(define)
不能在(if )
表单中使用,因为(if)
如何创建它自己的临时词法范围,以某种方式中断{ {1}}。
但是,作为一项解决方法,您可以翻转(define)
和if
程序:
define