Escolar Documentos
Profissional Documentos
Cultura Documentos
in Haskell
John Launchbury
Trevor Elliott
Motivating Example
Xen hypervisor
lift
O Lis
l iftI t
IO Orc List
putMVar <|>
readTVar
MonadIO MonadPlus
Basic Examples
fplang
metronome :: Orc ()
metronome = return () <|> (delay 2.5 >> metronome)
metronome
delay 2.5
()
Basic Examples
rsiReminder :: Orc ()
rsiReminder = do
metro 3600
email “john at galois.com” “Get up and stretch!!”
Search
queens = fmap show (extend [])
<|> return ("Computing 8-queens...")
else do
j <- liftList [1..8]
guard $ not (conflict xs j)
extend (j:xs)
MonadPlus
operation
conflict :: [Int] -> Int
conflict = ...
Search
*Main> printOrc (queens)
Ans = "Computing 8-queens..."
Ans = "[5,7,1,3,8,6,4,2]"
Ans = "[6,4,2,8,5,7,1,3]"
Ans = "[5,3,8,4,7,1,6,2]"
Ans = "[4,2,7,3,6,8,5,1]"
:
*Main> printOrc (queens)
Ans = "Computing 8-queens..."
Ans = "[4,2,7,3,6,8,5,1]"
Ans = "[6,4,7,1,8,2,5,3]"
Ans = "[3,6,4,2,8,5,7,1]"
Ans = "[2,7,3,6,8,5,1,4]"
:
Orc API
newtype Orc a
x
p
p q
(<#>) :: Orc a -> Orc b -> Orc a
p <#> q = do
end <- newEmptyMVar
(p <+> silent (putMVar end ()))
<|> silent (q `onlyUntil` takeMVar end)
Add a bound
msum’ :: Orc
Int Int -> [Orc
-> [Orc a]Orc
a] -> -> Orc
a a
msum’ bound ps = ...
Launch p only if a
wrap :: TVar Int -> Orc a -> Orc a resource is available
wrap t p = do
checkModifyTVar t (>0) (\x->x-1)
p <+> silent (modifyTVar_ t (+1))
• Layered implementation —
layered semantics
– Properties at one level depend
Orc Scripts
on properties at the level below
Orc Monad multiple results
• What properties should Orc terms
HIO Monad thread control
satisfy?
IO Monad external effects – Hence, what properties should
be built into HIO?
Transition Semantics
return x = \k -> k x
p >>= h = \k -> p (\x -> h x k)
Discard the
continuation
stop = \k -> return ()
p <|> q = \k -> fork (p k) >> q k Duplicate the
continuation
printOrc = runOrc $ do
a <- p
liftIO $ putStrLn ("Ans = " ++ show a)
HIO Monad
~~~~
~~~
~~~~
~~
~~~~ ~~
• Don’t want the programmer to have to do
~
~~
~ explicit thread management
~~~~ ~~
~~~
~~
~~~~
– Nested groups of threads
~~~~
~~~ • Want richer equational theory than IO
~~
~~~~~
~~
– e.g. by managing asynchronous exceptions
~~~
~ ~~
~~ ~~~~~
newtype HIO a =
~~~~ HIO {inGroup
~~~ :: Group -> IO a}
~~~~
type Group = (TVar Int, TVar Inhabitants)
~~~~
~
data Inhabitants ~~= Closed | Open [Entry]
data Entry = Thread ThreadId | Group Group
newPrimGroup :: IO Group
register :: Entry -> Group -> IO ()
killGroup :: Group -> IO ()
increment, decrement, isZero :: Group -> IO ()
Concluding
• Orc in Haskell
– Ready for use today for concurrent scripting
• cabal install orc
– Flexibility of embedded DSLs: discover new idioms
– Design principles emerge
• Two kinds of communications
• Many kinds of state elements
Eagerly-Swap:
do y <- eagerly p = do x <- eagerly q
x <- eagerly q y <- eagerly p
return (x,y) return (x,y)
eagerly p ?
eagerly p
p p
=
k put r k
a
a
saveOnce :: Orc a -> (MVar a,Group) -> HIO ()
p `saveOnce` (r,g) = do
ticket <- newMVar ()
p (\x -> takeMVar ticket >> putMVar r x >> close g)