Intro

The rise of single page application in the recent trend brings up many new frameworks in JavaScript land, and it comes with their own characteristic. Let's name few of them here: Angular, React, Vue, Mithril, Riot, Inferno, Ember, Can, Dojo, Polymer, etc. Then, we move to list another language that compiles to JavaScript: Dart, Gopher, Spine, GWT, Closure, ScalaJS, etc. From those lists, I can be sure that you familiar with three big names in JavaSript land which is Angular, React, and Vue as they heavily used in recent web development and a lot of tutorials available all over the web. From this moment allow me to introduce you Elm, a language that born from academic research and come into fields with slightly different approach.

Elm was written in Haskell by Evan Czaplicki in 2012 due to finish his thesis. Its adopt Functional Reactive Programming (FRP), advertise us with no runtime exceptions, great performance. What the heck is FRP and no runtime exceptions? Hold on buddy, I hope my explanation will make sense to you. FRP is a reactive programming (asynchronous data flow) which use building block of functional programming (e.g filter, map, reduce) put it simply that we deal with data streams using filter, map, reduce (this is caveman explanation for more insight you can read it here) and no runtime exceptions mean you will never get the exception while your program is running, and what is exception? If you have an experience with JavaScript you often find bla bla is not a function sound familiar? Heh.

You might come with another question why on earth I should use this language if JavaScript has flow and typescript? Of course you should not, but you will get a new approach about how to solve a problem in SPA specifically, yeah I can assure you because Redux and Vue is heavily influenced by Elm, you ever try to learn a purely functional programming such as Haskell, Idris, Miranda but overwhelm by their complexity, and last but not least Elm is designed to interoperability with JavaScript.

Basic Pattern

We can divide all Elm programs into Model, Update, View.

  • Model - the state of your application.
  • Update - a way to update your state.
  • View - a way to view your state.

    Let's dive in Elm architecture.

import Html exposing (..)

 -- MODEL

 type alias Model = { ... }

 -- Update
type Msg = Increment | Decrement

update : Msg -> Model -> Model

update msg model = 
    case of 
        Reset -> ...
        ...

-- VIEW
view : Model -> Html Msg 
view model = 
    ...   

That is Elm program in essence, pretty simple right? Before we create our first Elm program, we need to know about Elm syntax.

Comment

-- this is a single line comment

{--
this is a multiline comment
--}

Literals

'a' : Char
"abc" : String

True : Bool
False : Bool

42 : Int
3.14 : Float

"""
Multiline line string
"""

Conditionals

if elmIsGood then "You should try it" else "whut??"

case of 
    Increment -> state + 1
    Decrement -> state - 1

Cautions Elm is indentation sensitive.

Union Types

type Visibility = All | Active | Visible

We will dig in into this data types on Part 2.

Functions

oddOrEven n =
    if n % 2 \= 0 then 'Odd' else 'Even'

Type Aliases

type alias Point = { x:Float, y:Int }

Not all syntax are covered here, you can refer to the Elm documentation. In this example, we will create a simple counter.

-- simplecounter.elm
import Html exposing (Html, div, button, text, p)
import Html.Events exposing (onClick)
import Html.Attributes exposing (..)

main = 
    Html.beginnerProgram 
        { model = 0
        , view = view
        , update = update 
        }

type alias Model = Int

model : Model 
model = 0

type Msg = Increment | Decrement | OddIncrement

update : Msg -> Model -> Model
update msg model =
    case msg of
        Increment -> 
            model + 1

        Decrement -> 
            model - 1

        OddIncrement -> 
            if model % 2 /= 0 then model + 1 else model

view : Model -> Html Msg
view model =
    div [style[("margin", "30px")]]
       [
        p [ class "result-style" ] [text (toString model)],
        button [ class "button-style", onClick Decrement ] [ text "-"],
        button [ class "button-style", onClick Increment ] [ text "+"],
        button [ style[("margin-right", "5px"), ("height", "40px"), ("border-radius", "5px"), ("background-color", "orange"), ("cursor", "pointer")], onClick OddIncrement ] [ text "Increment if odd"]                              
       ]

The program will update the view whenever user click on decrement or increment button (update our Model via Update method).

Congratulations! You just create a program using Elm. In the next article we will cover more interesting Elm program, so please subscribe to our newsletter.

Install Elm using npm install -g elm and run elm-make simplecounter.elm --output=simplecounter.html to run the program.