2020-05-19 20:25:18 +03:00
|
|
|
module Main
|
|
|
|
|
|
|
|
import Channel
|
|
|
|
import Linear
|
|
|
|
|
|
|
|
data Cmd = Add | Append
|
|
|
|
|
|
|
|
Utils : Protocol ()
|
|
|
|
Utils
|
|
|
|
= do cmd <- Request Cmd
|
|
|
|
case cmd of
|
|
|
|
Add => do Request (Int, Int)
|
|
|
|
Respond Int
|
|
|
|
Done
|
|
|
|
Append => do Request (String, String)
|
|
|
|
Respond String
|
|
|
|
Done
|
|
|
|
|
|
|
|
utilServer : (1 chan : Server Utils) -> Any IO ()
|
|
|
|
utilServer chan
|
2020-06-12 13:18:12 +03:00
|
|
|
= do cmd # chan <- recv chan
|
2020-05-19 20:25:18 +03:00
|
|
|
case cmd of
|
2020-06-12 13:18:12 +03:00
|
|
|
Add => do (x, y) # chan <- recv chan
|
2020-05-19 20:25:18 +03:00
|
|
|
chan <- send chan (x + y)
|
|
|
|
close chan
|
2020-06-12 13:18:12 +03:00
|
|
|
Append => do (x, y) # chan <- recv chan
|
2020-05-19 20:25:18 +03:00
|
|
|
chan <- send chan (x ++ y)
|
|
|
|
close chan
|
|
|
|
|
|
|
|
MakeUtils : Protocol ()
|
|
|
|
MakeUtils = do cmd <- Request Bool
|
|
|
|
if cmd
|
|
|
|
then do Respond (Client Utils); Loop MakeUtils
|
|
|
|
else Done
|
|
|
|
|
|
|
|
sendUtils : (1 chan : Server MakeUtils) -> Any IO ()
|
|
|
|
sendUtils chan
|
2020-06-12 13:18:12 +03:00
|
|
|
= do cmd # chan <- recv chan
|
2020-05-19 20:25:18 +03:00
|
|
|
if cmd
|
|
|
|
then do cchan <- Channel.fork utilServer
|
|
|
|
chan <- send chan cchan
|
|
|
|
sendUtils chan
|
|
|
|
else close chan
|
|
|
|
|
|
|
|
getUtilsChan : (1 chan : Client MakeUtils) ->
|
Remove linearity subtyping
It's disappointing to have to do this, but I think necessary because
various issue reports have shown it to be unsound (at least as far as
inference goes) and, at the very least, confusing. This patch brings us
back to the basic rules of QTT.
On the one hand, this makes the 1 multiplicity less useful, because it
means we can't flag arguments as being used exactly once which would be
useful for optimisation purposes as well as precision in the type. On
the other hand, it removes some complexity (and a hack) from
unification, and has the advantage of being correct! Also, I still
consider the 1 multiplicity an experiment.
We can still do interesting things like protocol state tracking, which
is my primary motivation at least.
Ideally, if the 1 multiplicity is going to be more generall useful,
we'll need some kind of way of doing multiplicity polymorphism in the
future. I don't think subtyping is the way (I've pretty much always come
to regret adding some form of subtyping).
Fixes #73 (and maybe some others).
2020-12-27 22:58:35 +03:00
|
|
|
One IO (LPair (Client Utils) (Client MakeUtils))
|
2020-05-19 20:25:18 +03:00
|
|
|
getUtilsChan chan
|
|
|
|
= do chan <- send chan True
|
2020-06-12 13:18:12 +03:00
|
|
|
cchan # chan <- recv chan
|
Remove linearity subtyping
It's disappointing to have to do this, but I think necessary because
various issue reports have shown it to be unsound (at least as far as
inference goes) and, at the very least, confusing. This patch brings us
back to the basic rules of QTT.
On the one hand, this makes the 1 multiplicity less useful, because it
means we can't flag arguments as being used exactly once which would be
useful for optimisation purposes as well as precision in the type. On
the other hand, it removes some complexity (and a hack) from
unification, and has the advantage of being correct! Also, I still
consider the 1 multiplicity an experiment.
We can still do interesting things like protocol state tracking, which
is my primary motivation at least.
Ideally, if the 1 multiplicity is going to be more generall useful,
we'll need some kind of way of doing multiplicity polymorphism in the
future. I don't think subtyping is the way (I've pretty much always come
to regret adding some form of subtyping).
Fixes #73 (and maybe some others).
2020-12-27 22:58:35 +03:00
|
|
|
pure (cchan # chan)
|
2020-05-19 20:25:18 +03:00
|
|
|
|
|
|
|
closeUtilsChan : (1 chan : Client MakeUtils) ->
|
|
|
|
Any IO ()
|
|
|
|
closeUtilsChan chan
|
|
|
|
= do chan <- send chan False
|
|
|
|
close chan
|
|
|
|
|
|
|
|
doThings : Any IO ()
|
|
|
|
doThings
|
|
|
|
= do -- lift $ printLn "Starting"
|
|
|
|
schan <- Channel.fork sendUtils
|
|
|
|
res <- getUtilsChan schan
|
Remove linearity subtyping
It's disappointing to have to do this, but I think necessary because
various issue reports have shown it to be unsound (at least as far as
inference goes) and, at the very least, confusing. This patch brings us
back to the basic rules of QTT.
On the one hand, this makes the 1 multiplicity less useful, because it
means we can't flag arguments as being used exactly once which would be
useful for optimisation purposes as well as precision in the type. On
the other hand, it removes some complexity (and a hack) from
unification, and has the advantage of being correct! Also, I still
consider the 1 multiplicity an experiment.
We can still do interesting things like protocol state tracking, which
is my primary motivation at least.
Ideally, if the 1 multiplicity is going to be more generall useful,
we'll need some kind of way of doing multiplicity polymorphism in the
future. I don't think subtyping is the way (I've pretty much always come
to regret adding some form of subtyping).
Fixes #73 (and maybe some others).
2020-12-27 22:58:35 +03:00
|
|
|
let (uchan1 # schan) = res
|
2020-05-19 20:25:18 +03:00
|
|
|
lift $ printLn "Got Chan 1"
|
Remove linearity subtyping
It's disappointing to have to do this, but I think necessary because
various issue reports have shown it to be unsound (at least as far as
inference goes) and, at the very least, confusing. This patch brings us
back to the basic rules of QTT.
On the one hand, this makes the 1 multiplicity less useful, because it
means we can't flag arguments as being used exactly once which would be
useful for optimisation purposes as well as precision in the type. On
the other hand, it removes some complexity (and a hack) from
unification, and has the advantage of being correct! Also, I still
consider the 1 multiplicity an experiment.
We can still do interesting things like protocol state tracking, which
is my primary motivation at least.
Ideally, if the 1 multiplicity is going to be more generall useful,
we'll need some kind of way of doing multiplicity polymorphism in the
future. I don't think subtyping is the way (I've pretty much always come
to regret adding some form of subtyping).
Fixes #73 (and maybe some others).
2020-12-27 22:58:35 +03:00
|
|
|
(uchan2 # schan) <- getUtilsChan schan
|
2020-05-19 20:25:18 +03:00
|
|
|
lift $ printLn "Got Chan 2"
|
|
|
|
closeUtilsChan schan
|
|
|
|
|
|
|
|
uchan1 <- send uchan1 Add
|
|
|
|
uchan2 <- send uchan2 Append
|
|
|
|
uchan2 <- send uchan2 ("aaa", "bbb")
|
2020-06-12 13:18:12 +03:00
|
|
|
res # uchan2 <- recv uchan2
|
2020-05-19 20:25:18 +03:00
|
|
|
close uchan2
|
|
|
|
lift $ printLn res
|
|
|
|
|
|
|
|
uchan1 <- send uchan1 (40, 54)
|
2020-06-12 13:18:12 +03:00
|
|
|
res # uchan1 <- recv uchan1
|
2020-05-19 20:25:18 +03:00
|
|
|
close uchan1
|
|
|
|
|
|
|
|
lift $ printLn res
|
|
|
|
|
|
|
|
main : IO ()
|
|
|
|
main = run doThings
|