[I accidentally sent an incomplete version, here’s the rest]

Under the assumption that continuations are used as a form of userspace 
context-switching and that dynamic-wind is used for cleanup (and maybe 
acquisition if you want to) of resources (and this cleanup shouldn’t be caused 
by context switching), I do have a solution (LGPL3+, albeit perhaps with an 
argument for triviality):

https://github.com/wingo/fibers/blob/f92e5cb4f78e7e3d3537bfc9622bc59ea99fe9a7/fibers/scheduler.scm#L281

It’s a bit ad-hoc currently, but I imagine it would be possible to:

• rename the currently-existing dynamic-wind to primitive-dynamic-wind
• create a fluid (not parameter!) %dynamic-wind-stack
• define (dynamic-wind a b c) as ((fluid-ref* %dynamic-wind-stack 0) a b c 0)
• initial value for %dynamic-wind-stack is (lambda (a b c n) 
(primitive-dynamic-wind* a b c))
• replacements for dynamic-wind (implemented by userspace threading 
equivalents) can be added by a fluid binding, and typically all 
‘dynamic-winders’ (except primitive-dynamic-wind) would be implemented by 
calling binding before it (positions indicated via ‘n’)

After some API abstraction to somehow hide the fluid and the argument ‘n’, this 
seems like a simple and composable replacement for dynamic-wind to me. (Some 
overhead involved, but it’s not like you would call dynamic-wind in a tight 
loop.)

Technically it’s technically against the RnRS rules, but IMO winding and 
continuation is a matter of perspective – I mean, a syscall is a 
kernel<->userspace abort-to-prompt, yet typically you don’t want dynamic-wind 
to consider those as non-local control flow.

Best regards,
Maxime Devos

Reply via email to