Вы можете добиться того же:
(define (prod-iter lst) (fold * 1 (remove zero? lst)))
... хотя он мог бы работать лучше, пройдя только один раз.
Для продолжения напомните (каламбур предназначен), что все вызовы / cc ждут, пока "k" будет применен следующим образом:
(call/cc (lambda (k) (k 'return-value)))
=> return-value
Хитрость в том, что вы можете позволить call / cc возвращать свое собственное продолжение, чтобы его можно было применить в другом месте после возврата call / cc следующим образом:
;; returns twice; once to get bound to k, the other to return blah
(let ([k (call/cc (lambda (k) k))]) ;; k gets bound to a continuation
(k 'blah)) ;; k returns here
=> blah
Это позволяет продолжению возвращаться более одного раза, сохраняя его в переменной. Продолжения просто возвращают значение, к которому они применяются.
Замыкания - это функции, которые переносят свои переменные окружения вместе с ними до того, как аргументы будут ограничены. Они обычные лямбды.
Стиль передачи продолжения - это способ передачи замыканий в качестве аргументов для последующего применения. Мы говорим, что эти аргументы замыкания являются продолжением. Вот половина текущего кода из моего генератора / решателя судоку в качестве примера, демонстрирующего, как стиль передачи продолжения может упростить ваши алгоритмы:
#| the grid is internally represented as a vector of 81 numbers
example: (make-vector 81 0)
this builds a list of indexes |#
(define (cell n) (list (+ (* (car 9) (cadr n))))
(define (row n) (iota 9 (* n 9)))
(define (column n) (iota 9 n 9))
(define (region n)
(let* ([end (+ (* (floor-quotient n 3) 27)
(* (remainder n 3) 3))]
[i (+ end 21)])
(do ([i i
(- i (if (zero? (remainder i 3)) 7 1))]
[ls '() (cons (vector-ref *grid* i) ls)])
((= i end) ls))))
#| f is the continuation
usage examples:
(grid-ref *grid* row 0)
(grid-set! *grid* region 7) |#
(define (grid-ref g f n)
(map (lambda (i) (vector-ref g i)) (f n)))
(define (grid-set! g f n ls)
(for-each (lambda (i x) (vector-set! g i x))
(f n) ls))