Песочница

Одноразовые продолжения и dynamic-wind

Текущий `call/cc` создаёт одноразовое продолжение только для выхода вверх; повторный вход запрещён, а передача управления выражена явными сигналами интерпретатора.

Когда это нужно

Сначала используйте обычные if, cond и процедуры. call/cc нужен лишь для одного явного выхода вверх из глубоко вложенного вычисления, а dynamic-wind — когда вход и очистка должны обрамлять такой выход.

Проверьте запуском

LISPEX
(call/cc (lambda (escape) (escape 'done) 'unreachable))

Наблюдаемый результат

OUTPUT
done

Разбор примера

call/cc передаёт процедуру выхода в lambda. Её вызов с done немедленно переносит значение во внешний call/cc; символ unreachable не вычисляется. Этим переносом продолжение расходуется.

Как рассуждать

  • Первый вызов атомарно потребляет продолжение до передачи; каждый последующий вызов даёт E340.
  • dynamic-wind выполняет before, затем основную процедуру и after; при раскрутке ожидающие after запускаются изнутри наружу.
  • Новая ошибка или выход из процедуры after заменяет уже передаваемый сигнал.

Быстрый выбор

ЗадачаПредпочтениеПричина
обычный выборif или condлокальный поток остаётся видимым
возврат из помощникаобычный результат процедурынет нелокального переноса
однократный выход через несколько вызововвыход call/ccодин явный путь вверх
очистка вокруг возможного выходаdynamic-windafter выполняется при раскрутке
многократное возобновление одной точкиперестроить потокпродолжение одноразовое и нерекурсивное

Частая ошибка

Многократное повторное использование продолжений и повторный вход в динамический контекст отложены.

Текущие границы

  • Исключения и продолжения среды не реализуют гостевую передачу.

Куда дальше

Обычный поток управления описан в условиях, а взаимодействие ошибок с сигналами вычислителя — в диагностике.

Условия · Диагностика