So, tonight, I had an idea for something that I'm not sure if it's either useful, efficient, interesting or anything other than a waste of time. It was an idea for the emulation of mutable variables, using functions as a way of storing the values in an accumulating parameter of sorts. They could safely be shared between threads, and could (and sort of do) support atomic actions.
It turned out to be really simple to implement, and I think just showing you the code would explain what I'm on about more than anything else. I don't know how else this could be extended (I'm sure it could be though, for some fairly interesting ideas), and since it has been written in the wee hours of the morning, I may be doing some pretty stupid stuff...
So, I'd love to hear some discussion (though yes, I do already know this could probably be done with MVars or TVars or what have you) and ideas, and here's the code:
module ASTM where import Control.Concurrent import Control.Concurrent.MVar import Control.Concurrent.Chan data Transaction a = Put a | Get (MVar a) | Mod (a -> a) | Atom (a -> Bool) (a -> a) (a -> a) (MVar Bool) data AVar a = AVar (Chan (Transaction a)) newAVar :: a -> IO (AVar a) newAVar x = do chan <- newChan :: IO (Chan (Transaction a)) forkIO (handler chan x) return (AVar chan) where handler chan x = do req <- readChan chan case req of Put a -> handler chan a Get mvar -> do putMVar mvar x handler chan x Mod f -> handler chan (f x) Atom test y n res -> if test x then do putMVar res True handler chan (y x) else do putMVar res False handler chan (n x) putAVar (AVar chan) x = writeChan chan (Put x) modAVar (AVar chan) f = writeChan chan (Mod f) getAVar (AVar chan) = do res <- newEmptyMVar writeChan chan (Get res) takeMVar res condModAVar (AVar chan) p t f = do res <- newEmptyMVar writeChan chan (Atom p t f res) takeMVar res

Leave a comment