Опытные функции get-first, get-next и waddle от Schemer

(define get-first
  (lambda (l)
    (call-with-current-continuation
      (lambda (here)
        (set! leave here)
        (waddle l)
        (leave (quote ()))))))

(define get-first
  (lambda (l)
    (call-with-current-continuation
      (lambda (here)
        (set! leave here)
        (leave (waddle l))))))

Для тех, кто не знаком с книгой "Закаленный интриган", get-first, get-next, а также waddle (последние два не определены здесь) являются процедурами, по-видимому, для моделирования сопрограмм для итерации по дереву, переданному в waddle что дает только листья. Просто до waddleПри втором и последнем повторном входе он устанавливает точку повторного входа туда, где он будет только когда-либо возвращать чистое значение. '() то есть вместо того, чтобы уступать '(), фактическая стоимость waddle является '() Как будто это была чистая функция с самого начала.

Имея это в виду, мы можем увидеть, что get-first устанавливает... Когда waddle возвращает "по-настоящему", он будет внутри call/cc в get-first а потом (leave (quote ())) это значение get-first (и, в свою очередь, это leave предназначен для возвращения к get-next на последней итерации, поэтому это get-next что делает "фактическое" возвращение '()).

Так почему же вторая версия не эквивалентна, где waddleценность '() был бы аргумент leave?

1 ответ

Путаница в том, чтоleave"это не та функция, которой я хочу, а функция, которую он оценивает при оценке, которая выглядит слева направо и, следовательно, раньше"waddle". Это означает, что он оценивает то, к чему он был только что установлен в предыдущем заявлении.

Мораль: будьте осторожны при использовании функций, которые подлежат переопределению в вызове функции! Если бы это было на переводчике справа налево, waddle будет оцениваться до символа leave была рассмотрена как функция, которая "уходит" куда угодно, в течение этого времени она будет установлена ​​на РАЗЛИЧНУЮ функцию.

Другие вопросы по тегам