与 Racket 代码中的 "do" 变量混淆

Confused with "do" variables in Racket code

不明白为什么 "a" 和 "b" 在代码中工作?我们应该定义 var "a" 和 "b" 前 "do" ?

(define v1 3)
(define v2 2)
(do ((a 1 (+ a v1))
     (b 2 (+ b v2)))
  ((>= a b) (if (= a b) 'YES 'NO)))

(do之后定义了do循环的局部变量:

  • (a 1 (+ a v1)) 含义:定义局部循环变量a,起始值为1,并在新一轮开始时将(+ a v1)赋值给a
  • (b 2 (+ b v2)) 含义:定义局部循环变量b,起始值为2,并在新一轮开始时将(+ b v2)赋值给b

因此,ab 是在 do 循环中定义的。

除了过程调用之外,没有控制流操作。 do 只是一个宏。 R5RS报告给出了一个实现:

(define-syntax do
  (syntax-rules ()
    ((do ((var init step ...) ...)
       (test expr ...)
       command ...)
     (letrec
         ((loop
           (lambda (var ...)
             (if test
                 (begin
                   (if #f #f)
                   expr ...)
                 (begin
                   command
                   ...
                   (loop (do "step" var step ...)
                         ...))))))
       (loop init ...)))
    ((do "step" x)
     x)
    ((do "step" x y)
     y)))

你的代码变成这样:

(let loop ((a 1) (b 2))
  (if (>= a b)
      (if (= a b) 'YES 'NO)
      (loop (+ a v1) (+ b v2))))