> On Feb 6, 2020, at 02:28, Simon Marlow <[email protected]> wrote:
> 
> The issue here is that raiseAsync is destructive - it *moves* the stack to 
> the heap, rather than copying it. So if you want to continue execution where 
> you left off, for shift#, you would have to copy it back onto the stack 
> again. That's the point I was trying to highlight here.

Ah, yes, I see what you mean! It happens that for my use case I actually do 
want to unwind the stack when I capture a continuation, so that isn’t a problem 
for me.

> Yes, these are all the things that make raiseAsync tricky! You can either 
> copy what raiseAsync does (but be warned, it has taken a lot of iteration to 
> get right) or try to use raiseAsync and/or modify it to do what you want.

My point was more that I’m unsure that shift# should handle most of those 
cases. For raiseAsync, it makes sense, since asynchronous interrupts can, by 
their nature, occur at any time, even during pure code. But my shift# operation 
lives in IO, and the intent is to only capture up to a reset# in the same state 
thread.

My justification for this is that if you could use shift# in pure code, it 
would be ill-defined what you’d even be capturing. Suppose you return a thunk 
containing a call to shift#. When the thunk is evaluated, you capture up to the 
nearest reset#… but who knows what that is now? This opens you up to all sorts 
of general badness.

Therefore, I don’t think there should ever be an UPDATE_FRAME in the captured 
continuation—if there is, it’s probably a bug. So unless someone can think of 
any valid use cases, I’ll make that more explicit by modifying the 
continuation-capturing code to add some assertions that those frames never 
appear in the captured stack.
_______________________________________________
ghc-devs mailing list
[email protected]
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs

Reply via email to