Wednesday, May 19, 2010

Haskell & STM, Why no Applicative?

There was a fellow on #haskell the other day who was apprehensive about learning STM. Should he learn it after learning category theory? We assured him that Haskell's STM was fairly simple, whereas category theory is a dense liberal art that you study to enrich your mind. Someone pointed him to the wiki and he went on his way.

Afterwards, I perused the wiki (again). What struck me was that there was no example there that show you how to convert a plain old bunch of IO routines into STM routines. When I went to make one myself, I realized how brain-dead easy it is, but that there's something missing...

Anyway, here's a chalked up example where someone has to perform multiple time-consuming tasks (preferably in parallel), with the interesting routine in bold:


import Control.Applicative
import Control.Monad
import Control.Concurrent
import Control.Concurrent.STM
import Control.Concurrent.STM.TMVar
import Data.DateTime
 
main :: IO ()
main =
    do putStrLn "Without STM"
       t1s <- getCurrentTime
       stuff <- withoutSTM
       t1e <- getCurrentTime
       putStrLn $ show stuff
       putStrLn $ "That took " ++ show (diffSeconds t1e t1s) ++ " seconds"
 

-- this is the routine that actually does stuff
withoutSTM :: IO GroceryStore
withoutSTM =
    do a <- getTomatoesCountFromDB
       b <- haveFreshBerries
       c <- getNameOfCurrentStore
       return $ GroceryStore a b c
 
getTomatoesCountFromDB :: IO Int
getTomatoesCountFromDB =
    do milliSleep 1000  -- simulate slow DB read
       return 5

haveFreshBerries :: IO Bool
haveFreshBerries =
    do milliSleep 1000
       return True

getNameOfCurrentStore :: IO String
getNameOfCurrentStore =
    do milliSleep 1000
       return "Tom's Produce"

data GroceryStore
    = GroceryStore
      { numTomatoes :: Int
      , freshBerriesInStock :: Bool
      , nameOfStore :: String
      }
    deriving (Eq, Show, Ord)
 
-- helpers
milliSleep = threadDelay . (*) 1000
 
 
 
So there you have the plain old imperative code.
 
And here is the same code modified to use STM.
 
 
-- getTomatoesCountFromDB, haveFreshBerries, getNameOfCurrentStore are unchanged from before

-- this is the modified routine
withSTM :: IO GroceryStore
withSTM =
    do a <- stmFork getTomatoesCountFromDB
       b <- stmFork haveFreshBerries
       c <- stmFork getNameOfCurrentStore

       GroceryStore <$> (stmWait a)
                    <*> (stmWait b)
                    <*> (stmWait c)

main :: IO ()
main =
    do putStrLn "With STM"
       t2s <- getCurrentTime
       stuffWithSTM <- withSTM
       t2e <- getCurrentTime
       putStrLn $ show stuffWithSTM
       putStrLn $ "That took " ++ show (diffSeconds t2e t2s) ++ " seconds"
       return ()

-- more helpers
stmWait = atomically

stmFork :: IO a -> IO (STM a)
stmFork m =
    do tmv <- newEmptyTMVarIO
       let m' = m >>= (atomically . putTMVar tmv)
       forkIO m'
       return $ readTMVar tmv
 
 
 
Now the folks who've been playing with this for a while won't find this particularly remarkable, but I wouldn't have used it a year ago when I was first learning Haskell, so I thought someone should make note of it. There are also two important things to take away from this.
 
1. You could only do this if imperative routines are treated as values. The pons asinorum that Eric S. Raymond was referring to is not without its benefits.
 
2. Would an applicative instance for STM be nicer? At the least, we might be able to do code like this instead.
 
       stmWait $ GroceryStore <$> a <*> b <*> c
 

What would be wrong with the naive implementation of this?  e.g.:
 
(<*>) :: (Functor m, Monad m) => m (a -> b) -> m a -> m b
(<*>) mf ma =
    do a <- ma
       f <- mf
       return $ f a
 
 
Again, I'm probably way out of my depth here, so I apologize profusely if this is asinine.

Posted via email from lambdasquirrel's posterous

Wednesday, May 5, 2010

Academia isn't Broken. We Are.

I saw this piece on Hacker News this morning. It struck a chord, but something wasn't right about it.

http://brucejacob.tumblr.com/post/373498114/academia-and-the-decline-of-wealth-in-america

If academia is contributing to the lack of innovation in this country, then maybe it's because we expect the wrong things from academia? I don't mean to say this as another pompous American, but when I used to chat with friends from abroad back in school, I was struck by how many of them had a uniform educational experience. This wasn't a blanket effect and there were more than enough exceptions to produce many of the most awesome researchers I've met. Back at home though, even the countries that had effective programs to retain their top talent suffered from a lack of innovation.

By contrast, there is no standard curriculum at the top 5 US universities for CS. But most of the kids coming out there are shills anyway. I went to one of the good schools, and many kids (and their parents) were concerned about whether what they were learning would "prepare them for the real world". That basically meant: did it teach you Java or consulting? You see what's happening? What our education system didn't do to them, their own expectations of college did, and sadly, they seem to have done it to themselves just as badly as the education system of those foreign countries did.

But education isn't about churning out stamped spoons, and that's why crap like that No Child Left Behind Act bothered me so much. Where we went wrong is that we began viewing education as something everyone is entitled to, for all the wrong reasons. Education is not factory farming. Steve Jobs took calligraphy because he thought it was interesting, and no one thought what the Google guys were doing was "practical". I'll wager that the Google guys did it because it seemed like nerdy awesomeness to transform web search into a giant linear algebra problem. Just as Academia is about exploring the boundaries of what we know, Education is about enriching one's thought process, and that's the leading source of innovation in our modern economy: good ideas from the fringe, implemented intelligently and autonomously.

The entitlement of success that seems to follow from attending college is what's broken. The expectation that you will get a cushy 9-5 job in return for that diploma is what's broken. It in essence is a laziness of the mind, an unwillingness to chart out one's own path, the very idea of which is quite unacademic.