Search code examples
schemecontinuationsdelimited-continuations

early exit with shift and reset


Trying to understand delimited continuations with Guile scheme

I managed to grasp the vanilla conts (call/cc) thanks to this video (it's great)

Now I'd like to move to delimited conts

I have this minimal example of early exit made with call/cc

(define (my-early-exit)
  (let ((
     my-val (call/cc
         (lambda (the-continuation)
           (display "this will be executed")
           (display "\n")
           (the-continuation 5) ;;early exit
           (display "this will not be executed")))))
    (display my-val)))

Ok, I can run this, I understand what it does

How can I write a piece of code equivalent to this one using shift and reset ?


Solution

  • I am confused about shift and reset but this is how I understand it, based on some notes I made on a little while ago. I'd welcome clarification and/or correction people who understand this better than I do.

    The equivalent thing, more or less, would be

    (define (mee/sr)
      (reset
       (display "this will happen\n")
       (shift k 5)
       (display "this won't happen, unless you call k\n")))
    

    So, here (if I understand this!):

    • reset establishes a 'place you can get to' in a similar way that call/cc does, except that there is no explicit variable for it;
    • (shift k ...) will:
      1. reset to the dynamically-nearest reset;
      2. evaluate ... with k bound to a continuation (? name) which, if called, will return its argument values from the shift form and then continue after it.

    So in this case I am not using k at all, so the forms after the shift never happen. But in this case:

    (define (another)
      (reset
       (display "here\n")
       (let ((v (shift k (k "and here\n"))))
         (display v))
       (display "and finally here as well\n")))
    

    Then

    > (another)
    here
    and here
    and finally here as well
    

    And lest this all seem too obvious:

    (define (yet-another)
      (reset
       (display "here\n")
       (let ((v (shift k
                       (k "and here\n")
                       (displayln "there is also Sheemish\n"))))
         (display v))
       (display "and finally here as well\n")))
    

    then

    > (yet-another)
    here
    and here
    and finally here as well
    there is also Sheemish
    

    There is a good amount of information on shift and reset here, although I do not completely understand them.