Even haskell, with its static types and referential transparency, is capable of emulating this pattern. Here's an example:
-- <a href="http://substack.net/scripts/RussianDoll.hs">RussianDoll.hs</a> -- Russian Doll principle in haskell module Main where import Control.Concurrent.MVar import Control.Monad (join) main :: IO () main = do fn <- newEmptyMVar putMVar fn $ do putStrLn "First!" swapMVar fn (putStrLn "Again!") >> return () join $ readMVar fn join $ readMVar fn join $ readMVar fn
Which when executed prints:
First! Again! Again!
An empty MVar is created and bound to fn. MVars are especially convenient for this example since they have an empty state built-in. The first time fn is executed, "First!" is printed, but then the fn MVar is swapped for a new action that prints "Again!".
The inferred type for fn is MVar (IO ()), so join can be used to execute the IO () action inside the MVar.
ghci> :t join join :: (Monad m) => m (m a) -> m a
:t join (readMVar (undefined :: (MVar (IO ())))) join (readMVar (undefined :: (MVar (IO ())))) :: IO ()
It's usually a better idea in these cases to use the shared mutable state to delegate to functions instead of storing and swapping the functions themselves. I am however optimistic that this approach could be used in some code to build a more beautiful abstraction.
git clone http://substack.net/blog.git