Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Rapid app development with Haskell - GovHack ex...

Rapid app development with Haskell - GovHack experience report

Learn what happened when three functional programming aficionadi
took on the GovHack open data competition armed with a Haskell compiler,
a handful of libraries and whole lot of hubris.

GovHack is an annual open data event in Australia. A coordinated
release of federal, state and local government data is celebrated
with a weekend-long hackfest, with prizes awarded for the most
interesting and useful apps, mashups or remixes.

Three hackers (including the presenter) who are passionate about
Haskell - a strongly typed, purely functional programming language -
decided to put their skills to the test and entered GovHack 2014 to
see what they could build in a weekend using Haskell.

Fraser Tweedale

November 04, 2014
Tweet

More Decks by Fraser Tweedale

Other Decks in Programming

Transcript

  1. About me Developer at Red Hat. FreeIPA identity management and

    Dogtag PKI. Mostly Python and Java at work. Mostly Haskell at home.
  2. This talk Part experience report; part Haskell/functional programming advocacy; part

    open data advocacy. What is Haskell? Why Haskell? GovHack project implementation details; wins and pain points. Field guide to Haskell web technologies
  3. The Haskell Programming Language Functional programming language Strong, static type

    system Pure (no side-effects) Lazy (only evaluates expressions if/when needed) Performance
  4. Why Haskell? Type system prevents many kinds of programmer errors.

    Purity → referential transparency → equational reasoning Powerful, beautiful abstractions. Don’t repeat yourself! High-quality libraries and frameworks. Why Functional Programming Matters; Hughes 1984. http://www.cse.chalmers.se/~rjmh/Papers/whyfp.pdf
  5. GovHack Annual open data event in Australia; weekend hackfest. Competition;

    do cool/useful things with newly-released data sets; prizes! All levels of govt involved; awesome that they are doing this; get behind it! Brisbane Functional Programming Group entered a team (3 people)
  6. GovHack - deciding the project Shortlisted a handful of datasets.

    Assessed data sanity, formats/syntax and usefulness. Considered writing libraries to parse/convert peculiar formats used in various data sets (unusual date formats, etc) Eventually decided on. . .
  7. GovHack - Brisbane Park Finder Search council parks in Brisbane

    by location and facilities. “Find a park near Chermside with BBQs and dog off-leash area” View map of park and surrounds including boundary with facilities marked on map with icons. http://brisparks.info/ UX sucks; enter if you dare! https://github.com/bfpg/brisparks.info
  8. Implementation - importing data Most datasets were CSV. cassava library

    for parsing CSVs into custom data types. Elegant and type-safe.
  9. Implementation - importing data Data type representing a park facility

    CSV record: data Facility = Facility { _facParkNumber :: Int , _facParkName :: Text , _nodeId :: Int , _nodeUse :: Text , _nodeName :: Text , _description :: Text , _easting :: Double , _northing :: Double }
  10. Implementation - importing data cassava; CSV parser instance for Facility

    data type: instance FromNamedRecord Facility where parseNamedRecord m = Facility <$> m .: "PR_NO" <*> m .: "PARK_NAME" <*> m .: "NODE_ID" <*> m .: "NODE_USE" <*> m .: "NODES_NAME" <*> m .: "DESCRIPTION" <*> m .: "EASTING" <*> m .: "NORTHING"
  11. Implementation - importing data cassava; import facilities from CSV: importFacilities

    :: Postgres -> IO () importFacilities db = do fileContents <- readFile "facilities.csv" case decodeByName fileContents of Left err -> putStrLn ("CSV parse error: " ++ err) Right facilities -> runWithDb (mapM_ insertFacility facilities) db
  12. Implementation - database postgresql-simple library; reading DB records: instance FromRow

    Facility where fromRow = Facility <$> field <*> field <*> field <*> field <*> field <*> field <*> field <*> field
  13. Implementation - database postgresql-simple library; writing DB records: instance ToRow

    Facility where toRow f = [ toField (f ^. facParkNumber) , toField (f ^. facParkName) , toField (f ^. nodeId) , toField (f ^. nodeUse) , toField (f ^. nodeName) , toField (f ^. description) , toField (f ^. easting) , toField (f ^. northing) ]
  14. Implementation - database postgresql-simple library; select facilities by park number:

    getFacilities :: Int -> Db [Facility] getFacilities id = query [sql| SELECT park_number, park_name, node_id, node_use, node_name, description, easting, northing FROM park_facility f WHERE f.park_number = ? |] (Only id) -- a single ? param
  15. Implementation - Snap Framework Haskell web framework Fast web server

    Snaplets to extend framework functionality templating, authentication, session management, DB etc. Scaffolding for quick setup
  16. Implementation - heist templating heist; Snap templating system. Interpolation: <div

    class="park" data-number="${parkNumber}"> <h4><parkName/></h4> <p>Located on <parkStreet/>, in <parkSuburb/>.</p> Some sanity checks at load time. mismatched tags; </p> found inside <div> tag I wish these were compile errors!
  17. Implementation - JavaScript PureScript is a pure, strongly-typed Alt-JS. Similar

    syntax to Haskell; similar expressiveness. FFI for safe interaction with impure JavaScript environment. In keeping with strongly-typed FP theme, decided to do the front-end in PureScript. One small problem. . . Noone actually knew PureScript Eventually abandoned for raw JavaScript.
  18. Retrospective “Haskell just got out of the way; pain points

    were other things.” “You can make changes at 3am; as long as the code is compiling you can come back and not be too afraid.” Loss of type safety at database interface bit us a few times. PureScript: don’t try to learn conceptually dense things during a hackfest. UX sucked; we needed someone with UX focus. Great fun. Would Haskell again. Bring on GovHack 2015.
  19. Servers WAI - Web Application Interface à la Rack, WSGI

    et al. Application, Middleware, Request, Response APIs Used by several (not all) frameworks Warp (HTTP server) The premier WAI handler Fast
  20. Frameworks Yesod Type-safe routes, URLs, templates. Scaffolding http://www.yesodweb.com/ Scotty Microframework

    à la Sinatra. https://github.com/scotty-web/scotty HappStack http://happstack.com/docs/crashcourse/index.html Silk rest Define REST APIs; generate client libs; auto docs Runs on Snap, HappStack or native WAI https://silkapp.github.io/rest/
  21. Deploying Haskell apps Platform as a Service (PaaS) OpenShift community

    cartridge Heroku buildpack FP Application Server (https://www.fpcomplete.com/) http://www.haskell.org/haskellwiki/Web/Cloud Lightning talk: http://is.gd/CNx0na Docker Haskell/GHC images: https://registry.hub.docker.com/ No official Language Stack for Haskell yet. DIY
  22. Summary Open data is important, and fun! You have useful

    skills, so get involved. You might win $$$ Functional programming matters. Lots of lessons learned in taking on GovHack in Haskell. Haskell is great for rapid (web) app development. FP + types + good libraries/frameworks = powerful combo. Deployment options still a bit immature. Don’t neglect UX!
  23. Resources Learn Haskell: https://github.com/bitemyapp/learnhaskell Snap Quick Start Guide: http://snapframework.com/docs/quickstart PureScript

    by Example: https://leanpub.com/purescript/ HaskellWiki: http://www.haskell.org/haskellwiki/Web GovHack: http://www.govhack.org/ BFPG: http://bfpg.org ; #bfpg (Freenode)
  24. Thanks for listening Copyright 2014 Fraser Tweedale This work is

    licensed under the Creative Commons Attribution 4.0 International License. To view a copy of this license, visit http://creativecommons.org/licenses/by/4.0/. Slides https://github.com/frasertweedale/talks/ Email [email protected] Twitter @hackuador