|
| 1 | +This is copied from some architectural notes on paper dated 2015-08-28. |
| 2 | +As such, it might be a bit outdated or totally confused. This is here |
| 3 | +to explain the thought with some of the design decisions. |
| 4 | + |
| 5 | +1. The current Ion implementation is very close to coroutines. In |
| 6 | +some sense, it's already a continuation. It "suspends" and |
| 7 | +"resumes" - but only on clock ticks right now. |
| 8 | +2. It looks feasible to force local state to be in the form of globals |
| 9 | +that (Haskell-wise) are local to the monad. |
| 10 | +3. To let me compose multiple Ions, multiple suspend and resume points |
| 11 | +must coexist. |
| 12 | +4. Globals will require some kind of prefix to not clash. (This |
| 13 | +applies really whether I do coroutines or not, as it applies |
| 14 | +anytime one instantiates a spec twice.) |
| 15 | +5. I can't see a meaningful way I should let Ion express _sequential_ |
| 16 | +code inside a coroutine. I see only Ivory code here. With this I |
| 17 | +can enforce the atomicity/synchronicity as in Atom, though I may |
| 18 | +need to 'lift' up variable access. |
| 19 | +6. At no point must 'suspend' be handled separately. It suspends at |
| 20 | +the end of flow in Ion anyway. The change is only in defining how |
| 21 | +it changes. |
| 22 | +7. We 'reify' that resume point into a continuation in the form of a |
| 23 | +function pointer by bundling a state that encodes position inside |
| 24 | +the spec where one resumes. |
| 25 | +8. No sensible way appears to exist of letting Ion scheduling happen |
| 26 | +_inside_ a coroutine. The Ion monad in general has no place inside |
| 27 | +a coroutine - the schedule's meaningless (we can't assign a phase |
| 28 | +at compile-time), and the components aren't sequential; Ivory's |
| 29 | +needed for most things. |
| 30 | +9. I might be able to move values around with a continuation still. |
| 31 | +10. Some Ivory ponderances: |
| 32 | + |
| 33 | +- Have ivoryEff return values; perhaps write to MemAreas. |
| 34 | +- Lift accesses to internal MemAreas to enforce Atom's stuff? |
| 35 | +- How could I do exceptions with this? |
| 36 | + |
| 37 | +11. Composition means that I must be able to call another Ion somehow. |
| 38 | +I'm not sure how yet. If I do so then it must convey its own |
| 39 | +return continuation for whatever resume point. (In the margins: |
| 40 | +Not exactly.) |
| 41 | +12. An important question: How would I get the continuation outside of |
| 42 | +that local scope so that I could schedule calls to it within Ion? |
| 43 | +13. Proposed code is like: |
| 44 | + |
| 45 | +> void ion_ ... (uint16_t state) { |
| 46 | +> if (state == 0) { |
| 47 | +> ... usual dispatch ... |
| 48 | +> } else if (state == 1) { |
| 49 | +> ... call resume at some point ... |
| 50 | +> } else if (state == 2) { |
| 51 | +> ... likewise ... |
| 52 | +> } |
| 53 | +> } |
| 54 | +
|
| 55 | +14. Could I meaningfully decouple the continuation stuff from the |
| 56 | +scheduling code? I still struggle, despite reasons around #1, #2, #10 |
| 57 | +to find a reason that coroutine/continuation needs to reside |
| 58 | +in Ion. |
| 59 | +15. Any approach that wants to pass a function pointer to an Ivory |
| 60 | +procedure at C runtime, and have that function pointed called, or even |
| 61 | +used at all, after that procedure has returned, will have to deal with |
| 62 | +the fact that one can't put a ProcPtr in a MemArea in Ivory. |
| 63 | +16. In what sense is the simple function call I generate a |
| 64 | +"continuation"? Is it only in the sense that I am using it to build |
| 65 | +things up in CPS? The key in Ivory's coroutine implementation is the |
| 66 | +abstraction it provides and the ability to clearly say 'suspend here, |
| 67 | +and resume here' while still behaving like a 'normal' Ivory procedure. |
| 68 | +So, perhaps what I have is nothing like coroutines, just an |
| 69 | +enabler/helper for CPS that can be async. |
| 70 | +17. The entire mechanism of 'delay' is a bit ambiguous. For instance, |
| 71 | +what is the phase at X here? 30, 50? Both anwsers and ugly and |
| 72 | +annoying in some way. In the software now, it's just 20 if the whole |
| 73 | +thing runs in phase 0. |
| 74 | + |
| 75 | +> phase 10 $ |
| 76 | +> ... |
| 77 | +> phase 20 $ |
| 78 | +> ... |
| 79 | +> delay 20 $ X |
| 80 | +
|
| 81 | +18. You can sort of fix 17 by having delay work only with the phase |
| 82 | +that is passed to it, e.g. |
| 83 | + |
| 84 | +> phase 10 $ |
| 85 | +> delay 20 $ ... -- phase 30 here |
| 86 | +> delay 30 $ ... -- phase 40 here |
| 87 | +> delay 40 $ do |
| 88 | +> ... -- phase 50 here |
| 89 | +> delay 50 $ ... -- phase 100 there |
| 90 | +
|
| 91 | +This is explicit and it works. The problems with it are that it |
| 92 | +trades off nice monadic expression with nested function composition, |
| 93 | +and that it nests deeper than otherwise needed, which can make for |
| 94 | +very lengthy node paths. |
0 commit comments