• If you are citizen of an European Union member nation, you may not use this service unless you are at least 16 years old.

  • Finally, you can manage your Google Docs, uploads, and email attachments (plus Dropbox and Slack files) in one convenient place. Claim a free account, and in less than 2 minutes, Dokkio (from the makers of PBworks) can automatically organize your content for you.


Haskell Python CPlusPlus

1. Haskell?

Functional, Pure, Lazy


2. Let's Re-write a Library

LLSD & LLIDL - a Network data interchange format & API description language


C++: 5,440 lines

     header: http://svn.secondlife.com/trac/linden/browser/trunk/indra/llcommon/llsd.h

     impl: http://svn.secondlife.com/trac/linden/browser/trunk/indra/llcommon/llsd.cpp


Python: 2,573 lines 

     impl: http://hg.secondlife.com/llbase/src/tip/llbase/llsd.py

     llidl: http://hg.secondlife.com/llbase/src/tip/llbase/llidl.py


Haskell: 1,049 lines


The base data type: 

data LLSD = LUndef
          | LBool Bool
          | LInt Int
          | LReal Double
          | LString String
          | LUUID UUID.UUID
          | LDate Time.UTCTime
          | LURI URI.URI
          | LBinary Byte.ByteString
          | LArray (M.Map Int LLSD)
          | LMap (M.Map String LLSD)


The core binary reader:

getLLSD :: Get LLSD
getLLSD = do
    c <- getChar8
    case c of
        '!' -> return undef
        '1' -> return $ toLLSD True
        '0' -> return $ toLLSD False
        'i' -> getInt32be >>= return . toLLSD
        'r' -> getWord64be >>= return . toLLSD . decodeIEEEDouble
        's' -> getString >>= return . toLLSD
        'u' -> getUUID >>= return . toLLSD
        'd' -> getWord64be >>= return . toLLSD . decodeDate
        'l' -> getString >>= return . toLLSD
                    . (fromLLSD . toLLSD :: String -> URI)
        'b' -> getInt32be >>= getLazyByteString . fromIntegral
                    >>= return . toLLSD
        '[' -> getLLSDArray
        '{' -> getLLSDMap
        _   -> fail $ "unrecognized binary tag: " ++ show c


Part of the parser for the IDL:

selector :: Parser LLIDL
selector =
    try (lexeme $ between (char '"') (char '"') name' >>= return . selectLLIDL)
    <|> (symbol "true" >> return (selectLLIDL True))
    <|> (symbol "false" >> return (selectLLIDL False))
    <|> ((lexeme $ integer) >>= return . selectLLIDL)


3. What was it like?

C++: "O, fuck, right, have to add const to that member function, in the .h and the .cpp..."

Python: "Okay, it ran... but what was that?"

Haskell: "Uhm, what is *that* compilation error.... OH! Right! That code does return a Maybe..."


4. Why should you care?

It's like crazy-moon language for about a month... and then you can deal with it

You actually write fewer type annotations than C++

The type checking actually finds real program errors, not just stupid typos

You can really really produce libraries that work at a high level of generalization


5. Resources

Good on-line easy intro to Haskell: Learn You a Haskell 

Excellent book, buy it or read it on-line: Real World Haskell
Portal to all things Haskell: Haskell.org
Enjoy!  - Mark (mark -at- glyphic -dot- com)