Thanks for taking the time to write such a detailed answer, I really
appreciated it.

Delimited continuations are useful since they return a value, and thus may
be reused and composed, and used to build complex control mechanisms.

In my opinion the coolest use of delimited continuations are Effects

http://math.andrej.com/wp-content/uploads/2012/03/eff.pdf

a way to separate pure computations and side effects that is more intuitive
and more composable than monads.

Brandon Bloom has written a (prototype) implementation of effect handlers
for clojure, based on the core.async CPS machinery

https://github.com/brandonbloom/cleff

Francesco




On Tue, Sep 22, 2015 at 10:19 PM, Nathan Davis <
nda...@positronic-solutions.com> wrote:

> On Tuesday, September 22, 2015 at 6:37:13 AM UTC-5, Francesco Bellomi
> wrote:
>>
>> Hi Nathan,
>>
>> I think it's an awesome project, thanks for sharing this.
>>
>>
> Thanks.  I appreciate the feedback.
>
>
>> I see that currently only full continuations are supported. Would it be
>> possible/feasible/easy to support delimited continuations? (ie. with ranges
>> different from the outermost CPS context)
>>
>>
> I haven't done much research into delimited continuations yet, so my
> understanding may be wrong.  However, here's my analysis of the current
> situation.
>
> As currently implemented, pulley.cps uses "sort of" full continuations.  I
> say "sort of" because continuations are implicitly limited by the
> trampoline.  So anytime a new trampoline is introduced (i.e., you call CPS
> code from a non-CPS function), the continuation is limited to that
> trampoline.  However, there is currently no way to explicitly delimit the
> continuation.
>
> In light of the above, it seems to me that *reset(f)* could be
> implemented as simply as a non-CPS function that invokes the (presumably
> CPS'd) function *f*.  I don't think this would be the ideal
> implementation, but it does seem to suggest it is at least possible.
>
> I'd be interested in hearing from you (and others) what use-cases you see
> for delimited continuations.  The overviews of the topic I've seen so far
> seem to neglect this entirely or only address it abstractly.  A few
> concrete examples would be a useful "jump-start".
>
> Also, it would be interesting to have a comparison with core.async's CPS
>> machinery: is pulley.cps expected to be more efficient performance-wise? Is
>> it implemented using similar or comparable techniques?
>>
>>
> core.async handles continuations as a state machine.  On the other hand,
> pulley.cps implements continuations via closures.  The two representations
> are isomorphic, so theoretically anything you can express in one you can
> express in the other.  However, state machines (at least as implemented in
> core.async) must be constructed with complete knowledge of all the possible
> states involved.  Since *go*-blocks are implemented via macro, and macros
> are limited to local transformations (and analysis), continuations (state
> transitions) within core.async are limited to the same *go*-block.
>
> In contrast, closures can come from different functions or even
> namespaces.  So continuations in pulley.cps can cross local boundaries.
> That is, even though pulley.cps transforms code blocks in isolation,
> closures allow these blocks to coordinate and participate in the CPS
> protocol.
>
> This has  some practical ramifications.  For example, you can't compose
> *go*-blocks the same way you compose regular functions.  In fact, you
> can't call a function in a *go*-block and, within that function, suspend
> the *go*-block.  You can of course compose core.async processes, but it
> has a distinct look and feel from function composition.
>
> On the other hand, functions transformed by pulley.cps compose just like
> regular functions — because they are functions.  In the examples directory,
> there is an implementation of a cooperative multitasking engine.  Unlike
> core.async, you can suspend tasks from pretty much any function.  There are
> still some limitations, but these are dynamic as opposed to static, and
> have to do with what I said previously about continuations being implicitly
> delimited.
>
> As far as performance goes, I haven't directly compared core.async to
> pulley.cps code yet, but I fully expect core.async to be a hands-down
> winner at this point.  core.async is more mature and has had more
> performance tuning than pulley.cps.  I have done some limited benchmarking
> against regular clojure code.  All I can say is that for compute-intensive
> code with tight loops in CPS code, pulley.cps performs pretty poorly.  You
> can expect a CPS version of such code to be 1 to 2 orders of magnitude
> slower than a non-CPS version.
>
> Interestingly, in included benchmark.clj (which benchmarks a few ways of
> computing the factorial function), one of the CPS implementations actually
> out-performed the non-CPS equivalent implemented via *loop* on OpenJDK 7
> for large n.  While for large n there is less time spent in CPS code and
> more time doing the actual multiplication, it is an interesting result
> because it means there was apparently some optimization it was able to
> perform on the CPS code that it wasn't able to do on the *loop* verion.
> On OpenJDK 8, the CPS code is consistently slower in all cases (though, as
> expected, the slow-down decreases as n increases).
>
>
>> thanks,
>> Francesco
>>
>>
>>
>>
>> On Monday, September 21, 2015 at 9:24:20 PM UTC+2, Nathan Davis wrote:
>>>
>>> I'm pleased to annouce the release of verion 0.2.0 of pulley.cps
>>> <https://github.com/positronic-solutions/pulley.cps>. pulley.cps is a
>>> macro-based source-to-source transforming compiler that transforms Clojure
>>> code into Continuation Passing Style (CPS), as well as a supporting
>>> run-time library.
>>>
>>>
>>> The main feature of this release is the addition of exception support —
>>> you can now use try, throw, and catch just like you would in regular
>>> Clojure code. There are various other enhancements as well, mostly to
>>> support the exception code, as documented in the changelog.
>>>
>>>
>>> Nathan Davis
>>>
>>> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to a topic in the
> Google Groups "Clojure" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/clojure/ugnV06e0Vlo/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to
> clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>



-- 
Francesco Bellomi

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to