3 ms·
Can anyone explain in a little more detail what's going on in the definition of the Scheme version of sum-of-squares? The previous example where the continuatio
by dmux 5y ago
Can anyone explain in a little more detail what's going on in the definition of the Scheme version of sum-of-squares? The previous example where the continuation of 2 + 1 + N is captured makes sense to me, but I'm having a hard time wrapping my head around the resulting continuation when a lambda is involved.
To make it a little cleaner, I've replaced the "receiver" definition with a function reference instead. What's the continuation here?
(define sum-of-squares
(lambda (bound)
(call/cc the-receiver)))
- valbaca 5y agoThe sum-of-squares isn't a continuation, rather it just loops through the squared-ints generator up to the bound. call/cc is used to allow some form control and allow the loop to exit > Before the sum-of-square function does anything, I use call/cc to capture the continuation, and assign it to the variable break. Notice that in the syntax of Scheme, this is the last step of the function. Therefore, calling break will immediately exist the function with a returned value, no matter where it is called.
- dmux 5y agoI've reread the quote you posted and think I may understand, although I'm probably misusing some terminology: since the call to call/cc is the only thing in the lambda definition, the continuation captured at that point is kind of the termination/return point of the function. If there was something after the call/cc, e.g. a (display "Done with looping") then invoking the continuation would break out of the loop and display "Done with looping."
- simiones 5y agoFirst of all, (define foo (lambda (args) body)) is just the Scheme idiom for defining functions. It's normally written `(define (foo args) body)` or Python `def foo(args): body`. In a little more detail, let's take a function that looks like this; I'll use the shorter syntax to avoid line noise: (define (sum-of-squares bound) 0) (print (sum-of-squares 100)) ;; prints "0" Now let's see what happens with a continuation: (define (sum-of-squares bound) (call/cc the-receiver)) ;; will return whatever is passed to current continuation ;; for now, it will jump to the receiver, passing the whole call stack to it (define (the-receiver cont) (cont 18)) (sum-of-squares 100) ;; will start executing sum-of-squares, then jump to the-receiver, passing it the call stack ;; then, the-receiver will jump back into sum-of-squares, replacing the value of the whole `call/cc` form with the value 18 ;; which will be returned to the top level This use is similar to the following Python code: def sum_of_squares(bound): try: the_receiver() except MyContinuation as e: return e.Value def the_receiver(): raise MyContinuation(18) To show some more power of what this can do, let's save the continuation to a global var and call it a few times: (define some-continuation '()) (define (sum-of-squares bound) (call/cc the-receiver)) ;; will return whatever is passed to current continuation ;; for now, it will jump to the receiver, passing the whole call stack to it (define (the-receiver cont) (set! some-continuation cont)) ;; the receiver stores the value of cont into some-continuation and returns control to the top level. ;; at this point, sum-of-squares and anything that was calling it has NOT finished executing: ;; it's frozen in the continuation (display (sum-of-squares 100)) ;;sets some-continuation to the continuation, doesn't print anything (some-continuation 18) ;; prints 18 (some-continuation 200) ;; prints 200 (display (+ 100 (sum-of-squares 100))) ;;sets some-continuation to a new vale, doesn't print anything (some-continuation 18) ;; prints 118 (some-continuation 200) ;; prints 300