Skip to content

Commit 5dfd601

Browse files
committed
Added some (old) architecture notes.
1 parent 07e3ca3 commit 5dfd601

File tree

1 file changed

+94
-0
lines changed

1 file changed

+94
-0
lines changed

notes.md

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
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

Comments
 (0)