tricu

An interpreted language for exploring Tree Calculus
Log | Files | Refs | README | LICENSE

interactionTrees.tri (2204B)


      1 !import "prelude"   !Local
      2 !import "io"        !Local
      3 
      4 -- Interaction Tree Effect Runtime
      5 --
      6 -- The IO system is an interaction-tree effect runtime interpreted by a
      7 -- small-step machine with a cooperative scheduler.  Primitive actions
      8 -- (putStr, readFile, writeFile, ...) are tagged nodes in an interaction
      9 -- tree.  Sequencing is performed by the single generic `bind` constructor.
     10 --
     11 --   pure x            -- lift a pure value into IO
     12 --   bind action k     -- run action, then apply k to its result
     13 --   thenIO a b        -- run a, discard its result, then run b
     14 --   mapIO action f    -- run action, then apply f to its result inside pure
     15 --
     16 -- The runtime supports several effects beyond basic IO:
     17 --   ask               -- read the current environment
     18 --   local f action    -- run action with environment transformed by f
     19 --   get               -- read the current mutable state
     20 --   put s             -- replace the mutable state
     21 --   fork action       -- spawn a concurrent task, returning a handle
     22 --   await handle      -- wait for a forked task to complete
     23 --   yield             -- yield control to the scheduler
     24 --   sleep ms          -- suspend current task for N milliseconds
     25 --
     26 -- File operations return a Result tree (see lib/base.tri):
     27 --   ok value     -- pair true  (pair value t)
     28 --   err msg      -- pair false (pair msg   t)
     29 --
     30 -- Use onReadFile / onWriteFile for convenient branching.
     31 --
     32 -- See demos/interactionTrees/ for smaller focused examples.
     33 
     34 -- Cooperative async demo.
     35 --   fork runs an action in the background.
     36 --   sleep suspends the current task for N milliseconds.
     37 --   await waits for a forked task and returns its value.
     38 --
     39 --   Here the child sleeps for 2 s while the parent prints immediately.
     40 --   The parent's message appears first, proving interleaving.
     41 
     42 asyncDemo = (
     43   bind (fork
     44     (bind (sleep 2000) (_ :
     45     bind (putStrLn "2000ms done sleeping!") (_ :
     46     pure "child2000 done"))))
     47   (handle2000 :
     48   bind (fork
     49     (bind (sleep 5000) (_ :
     50     bind (putStrLn "5000ms done sleeping!") (_ :
     51     pure "child5000 done"))))
     52   (handle5000 :
     53   bind (putStrLn "Parent first!") (_ :
     54   bind (await handle5000) (_ :
     55   await handle2000)))))
     56 
     57 main = io asyncDemo