2

在 linux 和 Mac OS 上使用 DrRacket,以下代码给出了这个错误

*: expects type <number> as 1st argument, given #<undefined>

但是如果我在过程定义的开头取消注释(换行符),它可以正常工作,产生预期值 9。

#lang r5rs

(define (quadr x y)
        ;(newline)
        (define xx (* x x))
        (define yy (* y y))
        (define xxyy (* xx yy))
        (+ xx yy xxyy))

(display (quadr 1 2))
(newline)

这是 Racket 的方案解释器中的一个错误,还是指定的语言使得 (define ...) 的嵌套调用可能发生乱序?如果是后者,我在哪里可以找到语言规范的相关部分?

顺便说一句,我非常了解“让”结构,并且知道这不是定义此类过程的推荐方式。不过,我没想到会出现这个错误。

4

1 回答 1

3

这是解释内部定义行为的 R5RS 规范的相关链接。请注意,第 5.2.2 节规定:

...必须可以在不分配或引用任何被定义的值的情况下评估<expression>a 中的每个内部定义。<body><variable>

换句话说,如果您的define值依赖于define相同内部定义中的先前 d 值,则您不能指望正确的行为。用于let*此:

(define (quadr x y)
  (let* ((xx   (* x x))
         (yy   (* y y))
         (xxyy (* xx yy)))
    (+ xx yy xxyy)))

或者更详细一点,使用几个嵌套let的 s:

(define (quadr x y)
  (let ((xx (* x x))
        (yy (* y y)))
    (let ((xxyy (* xx yy)))
      (+ xx yy xxyy))))

插入 a(newline)会导致变量定义在此示例中起作用,这是非常奇特的,但是当您处理未定义的行为时,任何事情都可能发生。作为旁注,如果我使用#lang racket而不是#lang r5rs,则原始代码对我有用,而无需额外的(newline).

于 2013-09-03T19:17:02.183 回答