The following example involves jumping into continuation and exiting out. Can somebody explain the flow of the function. I am moving in a circle around continuation, and do not know the entry and exit points of the function.
(define (prod-iterator lst)
(letrec ((return-result empty)
(resume-visit (lambda (dummy) (process-list lst 1)))
(process-list
(lambda (lst p)
(if (empty? lst)
(begin
(set! resume-visit (lambda (dummy) 0))
(return-result p))
(if (= 0 (first lst))
(begin
(call/cc ; Want to continue here after delivering result
(lambda (k)
(set! resume-visit k)
(return-result p)))
(process-list (rest lst) 1))
(process-list (rest lst) (* p (first lst))))))))
(lambda ()
(call/cc
(lambda (k)
(set! return-result k)
(resume-visit 'dummy))))))
(define iter (prod-iterator '(1 2 3 0 4 5 6 0 7 0 0 8 9)))
(iter) ; 6
(iter) ; 120
(iter) ; 7
(iter) ; 1
(iter) ; 72
(iter) ; 0
(iter) ; 0
Thanks.
The procedure iterates over a list, multiplying non-zero members and returning a result each time a zero is found.
Resume-visitstores the continuation for processing the rest of the list, andreturn-resulthas the continuation of the call-site of the iterator. In the beginning,resume-visitis defined to process the entire list. Each time a zero is found, a continuation is captured, which when invoked executes(process-list (rest lst) 1)for whatever valuelsthad at the time. When the list is exhausted,resume-visitis set to a dummy procedure. Moreover, every time the program callsiter, it executes the following:That is, it captures the continuation of the caller, invoking it returns a value to the caller. The continuation is stored and the program jumps to process the rest of the list.
When the procedure calls
resume-visit, the loop is entered, whenreturn-resultis called, the loop is exited.If we want to examine
process-listin more detail, let’s assume the list is non-empty. Tho procedure employs basic recursion, accumulating a result until a zero is found. At that point,pis the accumulated value andlstis the list containing the zero. When we have a construction like(begin (call/cc (lambda (k) first)) rest), we first executefirstexpressions withkbound to a continuation. It is a procedure that when invoked, executesrestexpressions. In this case, that continuation is stored and another continuation is invoked, which returns the accumulated resultpto the caller ofiter. That continuation will be invoked the next timeiteris called, then the loop continues with the rest of the list. That is the point with the continuations, everything else is basic recursion.