我有一个程序,我正在为一个类编写,用一个新变量替换最左边的变量。 (它实际上允许您自己提供等价关系)。问题是,在Chez Scheme 8.2中,如果最左边的一个出现在列表中,则它会替换最右边的出现。我们使用运行某种版本的方案的服务器(我不确定哪个版本),并且在服务器上它正确地替换了最左边的出现。以下是代码:
(define subst-leftmost
(lambda (new old ls proc)
(let ([keep-going? #t])
(letrec ([helper
(lambda (ls)
(cond [(null? ls) ls]
[(or (pair? (car ls)) (null? (car ls)))
(cons (helper (car ls)) (helper (cdr ls)))]
[(and keep-going? (proc old (car ls)))
(set! keep-going? #f) (cons new (cdr ls))]
[else (cons (car ls) (helper (cdr ls)))]))]) (helper ls))))
这被称为:(subst-leftmost'x'a'(d b c(a)b a)eq?),它应产生输出(d b c(x)b a),并在服务器上产生。然而,在Chez方案中,它产生(d b c(a)b x)。我认为差异是由于行
[(or (pair? (car ls)) (null? (car ls)))
(cons (helper (car ls)) (helper (cdr ls)))]
以非设定的顺序评估汽车的助手和cdr的助手。
我的问题是:哪个版本的方案遵循标准,如何修改我的代码以使其在两个版本中都能正常工作?
(我已经和我的教授谈过这件事了。周一他会在课堂上讲述这个问题,一旦他能想到这一点,但我很好奇。我也已经获得了分配的全部内容。所以在这方面不要担心帮助我的道德。)
答案 0 :(得分:4)
没有,抱歉。 Here's the relevant legalese.如果您需要按特定顺序评估子表达式,请使用LET或LET *。
答案 1 :(得分:2)
Scheme保证没有特定的顺序(如Cirno所说)。如果你的代码没有副作用,这没关系。
但是,您的代码是副作用(因为外部变量为set!
),所以,您有一些选择:
helper
函数不会更改其外的任何变量或状态使用适当的let
来确保您需要的订购(如Cirno建议的那样);特别是,将(cons (helper (car ls)) (helper (cdr ls)))
更改为:
(let ((depth-first (helper (car ls))))
(cons depth-first (helper (cdr ls))))