Hacker News new | ask | show | jobs
by convolvatron 1282 days ago
"Finally, a primitive (call-in-continuation) is provided that allows calling a procedure in a given continuation instead of just delivering values to it."

can anyone add some language about what this is? I read this and the section on it, and remain deeply confused

1 comments

I can try!

> (call-in-continuation cont proc obj …)

First, just some context, to be sure I've got my facts straight:

'call/cc' allows you to capture the continuation which invokes it. That continuation is represented as a procedure passed into a unary function. That function usually uses 'set!' to export the continuation into a broader scope before returning an initial value to call/cc's caller. Later, invoking that continuation with a value tosses your current continuation and returns you to the call-site of call/cc, where the call/cc form now returns to it's caller again but with the provided value.

In contrast, 'call-in-continuation' takes a procedure and some arguments. It tosses the current continuation, returning to the call-site of call/cc, but then instead of returning a supplied value directly to call/cc's caller, it returns the result of evaluating the given procedure (applying it to any other supplied arguments) here at the call/cc call-site.

Supplied arguments are evaluated before returning to the continuation, just like when invoking the continuation itself with some values.

Mirroring the example from Guile's docs[1]:

  (define kont #f)
  (let ((x 1))
    (format #t "the return is ~a\n"
            (call/cc (lambda (k)
                       (set! kont k)
                       (1+ x)))))
  ⇒ the return is 2
  
  (kont 3)
  ⇒ the return is 3
  
  (kont (+ x 3))
  ⇒ Unbound variable: x
  
  (kont (lambda () (+ x 3))
  ⇒ the return is #<procedure 1d823a8 at <unknown port>:5:6 ()>
  
  (call-in-continuation kont (lambda () (+ x 3)))
  ⇒ the return is 4
  
  (call-in-continuation kont (lambda (y) (+ x y)) 4)
  ⇒ the return is 5

[1]: https://www.gnu.org/software/guile/manual/html_node/Continua...
Oh, and a note on why you'd want this: while you may be able to construct a superficially similar example by expecting call/cc to return a thunk and evaluating it at the call-site, you can't always control the call-site and might be using one continuation in multiple contexts.

The try/catch implementation on page two of A Better API for First Class Continuations show-cases a specific use-case (albeit in the form of continuation-graft), though I'm still staring at it and trying to figure out if a few more parens and thunks wouldn't do the trick (more verbosely) in that context.