1

对于 SICP 课程,我们正在学习 Scheme,我们有一个任务要求我们检查一个点是否在轴对齐的矩形中。我是这样做的:

(define in-rect?
  (lambda (px py rx1 ry1 rx2 ry2) 
    (<= (* (- px rx1) (- px rx2)) 0) and
    (<= (* (- py ry1) (- py ry2)) 0))) 

我是根据我以前的 C 习惯这样做的,并在那里暂时忘记了波​​兰表示法。我们的在线辅导程序使用的解释器按照我的意图“正确”地运行此代码。但是,AFAIK,“and”的这种用法在语法上应该是错误的。当我尝试运行它时,DrRacket 指出了一个语法错误。

那么这是如何评估在线导师上每个测试用例的正确值的呢?这个选项是否也有效?

4

2 回答 2

0

for 的语法and与大多数表达式相同 - 它使用前缀表示法;它也可以有零个或多个参数,不一定是布尔表达式:

(and <exp1> <exp2> <exp3> ...)

对于您的代码,它应如下所示:

(define in-rect?
  (lambda (px py rx1 ry1 rx2 ry2) 
    (and (<= (* (- px rx1) (- px rx2)) 0)
         (<= (* (- py ry1) (- py ry2)) 0))))

至于为什么您的代码似乎在在线导师中工作,这是因为解释器可能使用三个表达式(第一个表达式,特殊形式,第二个表达式)评估了lambda内部隐式的主体,只返回最后一个条件的值。虽然它完全起作用很奇怪,因为没有参数通常会引发“错误语法”或类似错误 - 这完全取决于它是如何实现的,但看起来不像是符合标准的解释器。begin<=and<=and

为了确保一切都清楚,请查看文档,因为and来自 C 背景的行为与您所期望的略有不同。请记住,and在第一个错误条件下发生短路:

(and (+ 1 1) #f (/ 1 0)) ; will work without a division by zero error
             ^
   evaluation stops here
=> #f

并注意and返回它遇到的最后一个表达式的值,因为在 Scheme 中任何不是显式#f的,都被认为是 true:

(and #t (* 2 3) (+ 1 1))
                   ^
         evaluation stops here
=> 2
于 2013-10-06T15:45:19.557 回答
0
(<= (* (- px rx1) (- px rx2)) 0) 
and
(<= (* (- py ry1) (- py ry2)) 0)

实际上是三个不同的(潜在)值/表达式。因为您没有将它包装在 begin 中,所以解释器可能会根据您的实现返回最左边或最右边的 lambda 值。

您的在线解释器可能实现and为原始函数,而不是宏或语法,或者根本不会使用宏/语法关键字作为表达式。

如果解释器认为and有某种值(和/或是一个有效的表达式),它可以继续返回 lambda 主体中第三个表达式的第一个值。

于 2013-10-06T15:49:53.040 回答