Closed dsrw closed 3 years ago
Thinking about this a little more, could I make the synthesized proc a closure iterator?
I created a quick proof of concept for a synthesized closure iterator. The goto
pragma doesn't seem to work in a closure iterator, so I added a flag to optionally run in a while loop instead. I also had to add nnkIteratorDef
to the allowed proc list. Otherwise it didn't require any changes to Synthesis.
https://github.com/dsrw/Synthesis/commit/df8ba5930c404cf5f6cecd0f6ca26fde925152ec
I'm not sure if this is a good idea, but it's pretty close to what I'm looking for.
What you want is closure iterators or coroutines see: https://eli.thegreenplace.net/2009/08/29/co-routines-as-an-alternative-to-state-machines
And the very start of my research on continuations: https://github.com/weavers-guild/weave-io/blob/master/research/README.md#state-machine
The goto
pragma doesn't interleave within closure iterators because the implementation of closure iterators also rely on it https://github.com/nim-lang/Nim/blob/v1.4.2/compiler/closureiters.nim#L914
Synthesis could be used to implement closure iterators. You only need to store a "token" somewhere that just tells the state to run on next call.
The underlying notion underneath that you are looking for is "continuation" and "resumable functions", which represent what is the rest of the computation to run.
Note that you might want to use async code to manage that UI so that all events and their handlers are registered in an event loop and asyncdispatch or chronos or any other implementation you like deal with the closure iterators/state machine.
Thank you for the thoughtful response. I'm a fan of the declarative nature of Synthesis, but a big case
inside of a closure iterator sounds like a simpler way to get what I want. I'll try that and see how far I get.
I'm looking to use a state machine to manage my the ui for my app. It has a vimish modal interface where user events mean different things depending on both the mode and on other factors such as what is visible or has focus. It's a mess of spaghetti code currently, and I feel like a state machine could make it easier to evolve.
Could synthesis be a good fit here? In all of the examples I can find, synthesis is basically the "main loop" of whatever it happens to be managing. A state machine gets called and then runs until it reaches a terminal state, generally performing multiple transitions along the way. What I think I want is an object that I can pump events into one at a time that performs a single transition, then returns.
It seems like I could maybe achieve something like this by writing some behaviors that can jump to the correctcurrentState
based on a mutable object that gets passed to the synthesized proc, which then performs a transition, mutates the passed object, then interrupts and terminates. When the next user event comes in I'd call the proc again, passing the same state object and the new event.Edit: Closure iterators seem like a better solution.
Is this at all reasonable? I feel like it probably isn't, but I barely understand this stuff. Is there an obviously better approach that I'm not thinking of?