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

  • Social distancing? Try a better way to work remotely on your online files. Dokkio, a new product from PBworks, can help your team find, organize, and collaborate on your Drive, Gmail, Dropbox, Box, and Slack files. Sign up for free.


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)