Как начать снимать текущие продолжения в Racket
Я обучаюсь call/cc
в разделе "Ракетки" по типу бумаги. Продолжения на примере: исключения, поиск во времени, генераторы, потоки и сопрограммы 1.
В документе упоминается, что наиболее выгодный API получен из call/cc
предоставляя процедуру lambda (cc) (cc cc)
, Я понимаю это конкретно call/cc
вызов возвращает текущий первоклассный объект продолжения основной программе.
В следующем примере статья вызывает все это (right-now)
,
Я вижу, что внутри этого же примера cc
объект, возвращаемый вышеупомянутым call/cc
вызов всегда запускается впоследствии, применяя его к себе. Вот чего я не понимаю.
Я не вижу, что такого особенного в cc
как значение, поэтому я попытался запустить его как функцию с (cc ())
, или же (cc (lambda () ()))
, или даже (cc "whatever")
а также (cc)
, Никакой радости: очевидно, продолжение хочет только это приложение для себя, чтобы начать работать.
Это почему? Что является примером, который ясно иллюстрирует уникальность запуска cc (cc cc)
?
1 ответ
В
(let ((cc (current-continuation)))
...)
Продолжение (current-continuation)
является
(lambda (_)
(let ((cc _))
...)
Назовите это продолжение c0
,
Определение current-continuation
является:
(define (current-continuation)
(call/cc (lambda (cc) (cc cc))))
Так call/cc
звонки (lambda (cc) (cc cc))
с c0
в качестве аргумента:
((lambda (cc) (cc cc)) c0)
= (c0 c0)
Вставка значения c0:
((lambda (_)
(let ((cc _))
...)
c0)
который становится:
(let ((cc c0))
...)
Что означает, что внутри ...
идентификатор cc
теперь привязан к значению c0
,
Если (c0 42)
происходит в ...
Мы получаем:
(c0 42)
= ((lamdba (_)
(let ((cc _))
...)
42)
= (let ((cc 42))
...)
И сейчас cc
связан со значением 42.
В примере используются (procedure? cc)
а также (future-value? cc)
проверить, cc
связан с продолжением (если (procedure? cc)
верно) и / или другое значение (будущее значение здесь 42).
Итак, в:
(define (current-continuation)
(call/cc (lambda (cc) (cc cc))))
значение передается (lambda (cc) (cc cc)))
это продолжение. Если мы хотим получить его в свои руки, нам нужно вернуть его, и мы делаем это, передавая его в продолжение. Т.е. (cc something)
вернет что-то, и так как мы хотим получить само продолжение, мы используем (cc cc)
,