Monday, 13 August, 2018 UTC


Summary

Elm Language was specifically designed to build front-end applications, and it offers a great experience as a whole. Its most shiny features are:
  1. Great performance using the virtual DOM
  2. Functional language
  3. Safety through a Powerful type system
  4. State management using the built-in Elm architecture
  5. A powerful and helpful compiler
We will see how to achieve 3, 4 and 5 using React, Redux and Flow.
Let's look at some Elm code:
import Html exposing (Html, button, div, text) import Html.Events exposing (onClick) main = Html.beginnerProgram  { model = model  , view = view  , update = update  } -- MODEL type alias Model = Int model : Model model = 0 -- UPDATE type Msg = Increment | Decrement update : Msg -> Model -> Model update msg model = case msg of Increment -> model + 1 Decrement -> model - 1 -- VIEW view : Model -> Html Msg view model = div [] [ button [ onClick Decrement ] [ text "-" ] , div [] [ text (toString model) ] , button [ onClick Increment ] [ text "+" ] ] 
https://gist.github.com/haikyuu/abd1145667e02aee2332d55e0d99bd33
The beauty of Elm is that every Elm app is written using the same parts:
  • Model: what is the state of your app
  • Update: how to update the state
  • View: how to display the state
The syntax is a bit weird for newcomers but it just takes some getting used to.
And its equivalent (commented) using React, Redux and Flow:
//@flow import React from 'react'; import ReactDOM from 'react-dom'; import { createStore, bindActionCreators } from 'redux' import { Provider, connect } from 'react-redux' type Increment = { type: "INCREMENT" } type Decrement = { type: "DECREMENT" } type CounterActions = | Increment | Decrement type Action = CounterActions // whenever we add a reducer, we add its actions here //make sure dispatch can only dispatch our predefined actions //and returns the action dispatched type domainIdentity<T> = <A: T>(a: A) => A type Dispatch = domainIdentity<Action> type CounterState = number //reducer const counter = (state: CounterState = 0, action: CounterActions) =>{ switch (action.type) { case 'INCREMENT': return state + 1 case 'DECREMENT': return state - 1 default: (action: empty); //to make sure we handle all the actions //it will trigger a flow error when we forget a case !! return state } } //action creators const increment = (): Increment => ({ type: "INCREMENT" }) const decrement = (): Decrement => ({ type: "DECREMENT" }) // our global state, also needs to be modified whenever we add a reducer type State = CounterState // passing state to our component as props const mapStateToProps = (state: State) => ({state}) const mapDispatchToProps = (dispatch: Dispatch) => bindActionCreators({ increment, decrement, }, dispatch) //helper flow types .. should be in a config file type _ExtractReturn<B, F: (...args: any[]) => B> = B; /*export*/ type ExtractReturn<F> = _ExtractReturn<*, F>; //redux state and action creators types type ReduxProps = ExtractReturn<typeof mapStateToProps>; type ReduxActions = ExtractReturn<typeof mapDispatchToProps>; //View //we don't have any props except redux ones type Props = {} & ReduxProps & ReduxActions const App = ({ decrement, increment, state }: Props) =>( <div> <button onClick={decrement}>-</button>  <div>{state}</div>  <button onClick={increment}>+</button>  </div> ) //connect our component with the redux store const ConnectedApp = connect(mapStateToProps, mapDispatchToProps)(App) let store = createStore(counter) ReactDOM.render( (<Provider store={store}> <ConnectedApp /> </Provider>), document.getElementById('root') ); 
https://gist.github.com/haikyuu/a540268b3336a52de69ae94d8e3b9e3c
A few things to note:
  • Elm’s type system is much more powerful and descriptive than Flow (and typescript)
  • The Elm architecture is integrated in the language level, so you can achieve more with less code in Elm compared to how much boilerplate you need to write in Redux.
  • Redux was inspired from Elm architecture
If you cannot use Elm in your day job, you can still benefit from similar goodies using Flow.
You will also become a better React developer by learning Elm, so check it out.

by Alaoui Abdellah