Closed pbaille closed 4 years ago
That's a fundamental limitation of any syntax-based coroutine implementation. cr
can't rewrite code outside of its body, so as soon as the splitter symbol is wrapped into a plain function it's not workable anymore. (quoting the guide : we can't shift/reset across stack frames). core.async
's go
works the same way, javascript's generators as well.
It's not possible to achieve what you want without modifying the host platform. Your attempts work by accident, they will likely break in non-trivial situations and that's not something you should rely on. In my opinion, the less hacky way to fully emulate scheme-style shift
/reset
is to turn every shift
ing function into a macro, such that the code is inlined in the reset
block instead of being wrapped in an opaque lambda. For instance :
(defmacro yield [x] `(let [x# ~x] (shift k# (cons x# (k# ())))))
(reset (yield 1) (yield 2) (yield 3))
#_=> (1 2 3)
thank you a lot for your answer! (and for your really interesting work) The macro approach that you suggest is indead a better solution :)
I was reading https://en.wikipedia.org/wiki/Delimited_continuation along with the delimited continuation guide of cloroutine.
I came accross some questions along the way. because the semantics of
shift
are different.I've made that gist that tries to port the code of the wiki with cloroutine's delimited continuations: https://gist.github.com/pbaille/2b8d3427df830a71144d59554277fde9
any opinions or advices related to this will be welcome
thank you