November 4, 2017

Pure reducers in Elm

One of the most defining courses I took during university was “Functional Programming”. After being introduced to other paradigms such as object oriented programming in the bachelor years it was possible to learn Haskell in this course and thus delve deeper into the functional programming paradigm. At the end of the course I developed a web application using Snap. After that I got more involved into front end development using JavaScript and always missed the developer experience that I got when programming in Haskell.

Recently I took the time to experiment with Elm for a small project at work since it is being advertised as a type safe programming language with “no runtime exceptions in practice”. Since these were exactly the things I like about haskell I had high expectations and I was very pleased with the experience. I used Microsoft Visual code with a plugin that offers syntax support and type checking.

One thing that I (and apparently other people) didn’t like however is the way html templates are being written in Elm. This got me thinking about how it would be nice to be able to extract the data fetching logic from a react/redux application and make sure that those are handled with “no runtime exceptions” by writing them in Elm. Practically this would mean that we write reducers in Elm and treat them as black boxes from within a react redux application by just dispatching actions to them just as we are used to do with classical react/redux applications. This while still having react to handle the dom manipulation.

To achieve this I developed bindings to React that are similar as the ones in the popular react-redux library. To ease the adoption I implemented the API identically as the react-redux bindings. Hence there is a connect function that takes a mapStateToProps and mapDispatchToProps function and returns a connector to connect React compoments to the store. The implementation makes use of the React context API in similar fashion as react-redux does. For those interested please have a look at the repository where a small example is provided.