方案评估订单标准

时间:2011-04-02 07:46:50

标签: scheme

我有一个程序,我正在为一个类编写,用一个新变量替换最左边的变量。 (它实际上允许您自己提供等价关系)。问题是,在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的助手。

我的问题是:哪个版本的方案遵循标准,如何修改我的代码以使其在两个版本中都能正常工作?

(我已经和我的教授谈过这件事了。周一他会在课堂上讲述这个问题,一旦他能想到这一点,但我很好奇。我也已经获得了分配的全部内容。所以在这方面不要担心帮助我的道德。)

2 个答案:

答案 0 :(得分:4)

没有,抱歉。 Here's the relevant legalese.如果您需要按特定顺序评估子表达式,请使用LET或LET *。

答案 1 :(得分:2)

Scheme保证没有特定的顺序(如Cirno所说)。如果你的代码没有副作用,这没关系。

但是,您的代码副作用(因为外部变量为set!),所以,您有一些选择:

  • 使用Racket(承诺使用从左到右的顺序,上次我与Racket开发人员交谈时)
  • 构建代码以消除副作用,以便helper函数不会更改其外的任何变量或状态
  • 使用适当的let来确保您需要的订购(如Cirno建议的那样);特别是,将(cons (helper (car ls)) (helper (cdr ls)))更改为:

    (let ((depth-first (helper (car ls))))
      (cons depth-first (helper (cdr ls))))