Scheme - 无法在null语法环境中绑定名称:tmp

时间:2014-09-23 18:57:58

标签: scheme syntax-error

您好我想弄清楚如何在方案中的if语句中定义我的变量。我一直收到错误;无法在null语法环境中绑定名称:tmp ....

从我在线阅读的所有内容来看,我的语法是正确的。我不明白我是如何得到这个错误的。

这是我的代码:

(if (list? seq2)
    (if (list? seq1)
        (begin
          (define tmp (car seq1))
          (if (list? tmp)
               #t
               #f))
        #f)
    #f)

真假返回是为了测试,所以我可以看到事情的结局。

4 个答案:

答案 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)

存在称为andor的逻辑短路语法。基本上(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