Суть call-with-concurrent-continuation
, или для краткости call/cc
, - это возможность захватывать контрольные точки или продолжения во время выполнения программы. Затем вы можете вернуться к этим контрольным точкам, применив их как функции.
Вот простой пример, в котором продолжение не используется:
> (call/cc (lambda (k) (+ 2 3)))
5
Если не использовать продолжение, трудно заметить разницу. Вот несколько из них:
> (call/cc (lambda (k) (+ 2 (k 3))))
3
> (+ 4 (call/cc (lambda (k) (+ 2 3))))
9
> (+ 4 (call/cc (lambda (k) (+ 2 (k 3)))))
7
Когда вызывается продолжение, поток управления возвращается туда, где продолжение было захвачено call/cc
. Думайте о выражении call/cc
как о дыре, которая заполняется тем, что передается в k
.
list-iter
- это существенно более сложное использование call/cc
, и может быть трудно начать его использовать. Во-первых, вот пример использования:
> (define i (list-iter '(a b c)))
> (i)
a
> (i)
b
> (i)
c
> (i)
list-ended
> (i)
list-ended
Вот набросок того, что происходит:
list-iter
возвращает процедуру без аргументов i
.
- Когда вызывается
i
, мы немедленно захватываем продолжение и передаем его control-state
. Когда вызывается это продолжение, привязанное к return
, мы немедленно вернемся к тому, кто вызвал i
.
- Для каждого элемента в списке мы берем новое продолжение и перезаписываем определение
control-state
этим новым продолжением, что означает, что мы продолжим оттуда в следующий раз, когда наступит шаг 2.
- После настройки
control-state
для следующего прохождения, мы передаем текущий элемент списка обратно в return
продолжение, в результате чего получается элемент списка.
- Когда
i
вызывается снова, повторите, начиная с шага 2, пока for-each
не выполнит свою работу для всего списка.
- Вызовите продолжение
return
с помощью 'list-ended
. Поскольку control-state
не обновляется, он будет возвращать 'list-ended
каждый раз при вызове i
.
Как я уже сказал, это довольно сложное использование call/cc
, но я надеюсь, что этого достаточно, чтобы пройти через этот пример. Для более мягкого ознакомления с продолжениями я бы рекомендовал выбрать Опытный планировщик.
person
acfoltzer
schedule
12.04.2011
yield
, достаточно полезен, чтобы стоять сам по себе. Хотя, возможно, его стоит переименовать. - person acfoltzer   schedule 12.04.2011