To extend #150, I'm thinking about an extension that introduce some contextual type system.
static reasoning
async is a world description
own and borrow is a linear restriction
Rules
Here is how it work
o : T [own]
b : T [borrow]
fo : T [own] -> ?
fb : T [borrow] -> ?
afo : T [own] -> ? <async>
afb : T [borrow] -> ? <async>
sync world
fb o, fb b: ok
fo o: ok, but later program cannot use o
async world
afb o, afb b: ok, but have to wait a signal that shows borrow is complete
afo o: ok, no waiting, but have to ensure this is not in a waiting list
The idea behind these rules is own and borrow is fine to restrict under usual sync programming, but for async program, we will not know when does borrowing complete. Therefore, introduce a special operator to tell the program is waiting for a complete signal can tell a static checker this is fine, program will do the right thing.
For own moving, async world also make us must ensure the moving is unique. The good thing is, since own and borrow are linear restriction, it's easy to find out we are doing it wrong. Therefore, below program is invalid:
foo : T [own] -> unit <async>
foo t = do
// move & borrow together, wrong
await [afo t, afb t]
Notice that, we cannot make such program with usual sync world, one must invoke fo first or fb first. But in async programming, some form can do that (like waiting list above).
The t <async> is a monadic t with capabilities limitation, that leads some operators like
await : t <async> -> t (bind)
return : t -> t <async> (pure)
wait_borrow : t <async> -> unit (optional)
As you can see, wait_borrow is not required but maybe an enhancement, since we only need to wait borrowing complete, not the whole computation.
Own/borrow
Let's define a->b means change current status of description, then we have
own: 1->0, 1->0
borrow: a->a, 1->1 (polymorphic keep first limit)
start own: 1, 1
start borrow: 0, 1
Therefore
fo o changes o : t [1, 1] to o : t [0, 0], and disallow the following use
fb o keeps o : t [1, 1]
fb b keeps b : t [0, 1]
fo b is invalid, since b : t [0, 1] didn't provide [1, 1] for fo
Limitation
For static reasoning, we might have to give up something, like: out of *.wit, disallow ownership description
Conclusion
Hope this is a good start for static reasoning component model programming, I also have some advanced consideration for <> syntax, like <filesystem> can limit the capabilities a program can use. It has two side
For runtime, a provider, that's a description about it can access to which thing.
For user, that's a restriction, one can only invoke WASI functions under these worlds.
To extend #150, I'm thinking about an extension that introduce some contextual type system.
Rules
Here is how it work
o : T [own]
b : T [borrow]
fo : T [own] -> ?
fb : T [borrow] -> ?
afo : T [own] -> ? <async>
afb : T [borrow] -> ? <async>
fb o
,fb b
: okfo o
: ok, but later program cannot useo
afb o
,afb b
: ok, but have to wait a signal that shows borrow is completeafo o
: ok, no waiting, but have to ensure this is not in a waiting listThe idea behind these rules is own and borrow is fine to restrict under usual sync programming, but for async program, we will not know when does borrowing complete. Therefore, introduce a special operator to tell the program is waiting for a complete signal can tell a static checker this is fine, program will do the right thing.
For own moving, async world also make us must ensure the moving is unique. The good thing is, since
own
andborrow
are linear restriction, it's easy to find out we are doing it wrong. Therefore, below program is invalid:Notice that, we cannot make such program with usual sync world, one must invoke
fo
first orfb
first. But in async programming, some form can do that (like waiting list above).The
t <async>
is a monadict
with capabilities limitation, that leads some operators likeawait : t <async> -> t
(bind)return : t -> t <async>
(pure)wait_borrow : t <async> -> unit
(optional)As you can see,
wait_borrow
is not required but maybe an enhancement, since we only need to wait borrowing complete, not the whole computation.Own/borrow
Let's define
a->b
means change current status of description, then we have1->0, 1->0
a->a, 1->1
(polymorphic keep first limit)1, 1
0, 1
Therefore
fo o
changeso : t [1, 1]
too : t [0, 0]
, and disallow the following usefb o
keepso : t [1, 1]
fb b
keepsb : t [0, 1]
fo b
is invalid, sinceb : t [0, 1]
didn't provide[1, 1]
forfo
Limitation
For static reasoning, we might have to give up something, like: out of
*.wit
, disallow ownership descriptionConclusion
Hope this is a good start for static reasoning component model programming, I also have some advanced consideration for
<>
syntax, like<filesystem>
can limit the capabilities a program can use. It has two side