Стандарт оценки схемы заказа - PullRequest
3 голосов
/ 02 апреля 2011

У меня есть программа, которую я пишу для класса, чтобы заменить самое левое вхождение переменной новой переменной. (На самом деле это также позволяет вам обеспечить отношение эквивалентности самостоятельно). Дело в том, что в схеме Chez 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-left '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 ]

4 голосов
/ 02 апреля 2011

Нет, извините. Вот соответствующий юридический. Используйте LET или LET *, если вам нужно вычислять подвыражения в определенном порядке.

2 голосов
/ 02 апреля 2011

Схема не гарантирует конкретного заказа (как сказал Цирно). Если у вашего кода нет побочных эффектов, это не имеет значения.

Однако ваш код имеет побочный эффект (из-за внешней переменной set!), поэтому у вас есть несколько вариантов:

  • Использовать Racket (который использует порядок слева направо, когда я в последний раз разговаривал с разработчиком Racket)
  • Структурируйте ваш код, чтобы устранить побочные эффекты, чтобы ваша функция helper не изменяла никакую переменную или состояние вне ее
  • Используйте соответствующие let s для обеспечения необходимого заказа (как предложил Цирно); в частности, измените (cons (helper (car ls)) (helper (cdr ls))) на:

    (let ((depth-first (helper (car ls))))
      (cons depth-first (helper (cdr ls))))
    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...