Racket 的评估顺序有多确定?
How deterministic is Racket's evaluation order?
我想知道在使用 set!
时 Racket 的评估顺序是如何确定的。更具体地说,
#%app
是否总是从左到右评估其参数?
- 如果不是,不同参数的求值可以交织在一起吗?
以这个片段为例:
#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)
我想知道在使用 set!
时 Racket 的评估顺序是如何确定的。更具体地说,
#%app
是否总是从左到右评估其参数?- 如果不是,不同参数的求值可以交织在一起吗?
以这个片段为例:
#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)