Racket 的评估顺序有多确定?

How deterministic is Racket's evaluation order?

我想知道在使用 set! 时 Racket 的评估顺序是如何确定的。更具体地说,

  1. #%app 是否总是从左到右评估其参数?
  2. 如果不是,不同参数的求值可以交织在一起吗?

以这个片段为例:

#lang racket

(define a 0)
(define (++a) (set! a (add1 a)) a)

(list (++a) (++a)) ; => ?

最后一个表达式的计算结果是否可以不同于 '(1 2),例如 '(1 1)'(2 2)'(2 1)

我未能在 http://docs.racket-lang.org/reference 上找到明确的答案。

与Scheme不同,Racket保证从左到右。所以对于示例调用:

(proc-expr arg-expr ...)

您可以阅读 Guide 中的以下内容:(强调我的)

A function call is evaluated by first evaluating the proc-expr and all arg-exprs in order (left to right).

这意味着这个程序:

(define a 0)
(define (++a) (set! a (add1 a)) a)

(list (++a) (++a)) 
; ==> (1 2)

而且是一致的。对于 Scheme (2 1) 是另一种解决方案。您可以通过使用绑定来强制排序,并可以确保相同的结果,如下所示:

(let ((a1 (++ a)))
  (list a1 (++ a)))
; ==> (1 2)