Вот как использовать call / cc для сборки return
самостоятельно.
(define (example x)
(call/cc (lambda (return)
(when (< x 0) (return #f))
; more code, including possible more calls to return
0)))
Некоторые схемы определяют макрос под названием let / cc, который позволяет вам избавиться от некоторого шума лямбды:
(define (example x)
(let/cc return
(when (< x 0) (return #f))
0))
Конечно, если ваша Схема этого не делает, пусть / cc написать тривиально.
Это работает, потому что call / cc сохраняет точку, в которой он был вызван как продолжение. Он передает это продолжение в свой аргумент функции. Когда функция вызывает это продолжение, Scheme отказывается от созданного им стека вызовов и продолжает работу с конца вызова / вызова cc. Конечно, если функция никогда не вызывает продолжение, она просто возвращается нормально.
Продолжения не будут по-настоящему утомительными, пока вы не начнете возвращать их из этой функции или, возможно, не сохраните их в глобальной структуре данных и не вызовете их позже. В противном случае они похожи на любые структурированные операторы goto любого другого языка (в то время как / для / прерывания / возврата / продолжения / исключения / условия).
Я не знаю, как выглядит ваш полный код, но, возможно, было бы лучше использовать cond и разделить сложные проверки на отдельные функции. Необходимость return
и let*
обычно является признаком чрезмерно императивного кода. Однако метод call / cc должен заставить ваш код работать на данный момент.