Skip to content

Instantly share code, notes, and snippets.

@srikumarks
Last active December 21, 2015 19:29
Show Gist options
  • Save srikumarks/bc9a5205a51759ee5398 to your computer and use it in GitHub Desktop.
Save srikumarks/bc9a5205a51759ee5398 to your computer and use it in GitHub Desktop.
Elm for Javascripters

Basics

  • Elm code is written as expressions. The end goal of an Elm programm is to specify a main expression which will be a Signal of Html values.
  • Line comments in Elm are marked using -- and are equivalent to // in JS.
  • Block comments in Elm are marked using {- and -} which are equivalent to /* and */ in JS.

Modules

module ModuleName where
-- Definitions

Functions

function norm(a,b) {
    return a * a + b * b;
}

is written as

norm a b = a * a + b * b

Application

norm(2.0,3.0)

would be written as

norm 2.0 3.0

i.e. no parentheses or punctuations necessary. This also means that norm 2.0 is a function that takes a float argument and produces a float value.

Anonymous functions

Anonymous functions are written using lambda syntax.

var norm = function (a, b) { return a * a + b * b; }

would be written as

norm = \a b -> a * a + b * b

where you read \ as "lambda" or "function" with the -> demarcating the argument list from the value expression.

Local bindings

function dist(a,b) {
    var n = a * a + b * b;
    return Math.sqrt(n);
}

would be written as

dist a b = 
  let n = a * a + b * b
  in sqrt n

Conditions

In JS, if-then-else construct is a statement, but in Elm it is an expression.

if condition_expression then
    positive_expression
else
    negative_expression

Case analysis

There is really no true equivalent of Elm's case expression in JS, but it is like switch.

function whoami(a) {
    switch (a) {
        case "planet": return "earth";
        case "system": return "solar";
    }
}

would roughly translate to

whoami a =
  case a of
    Planet -> Earth
    System -> Solar

The difference is that the Elm code will bomb if all possible cases of the value aren't covered.

Type description

JS is dynamically typed and so there is no equivalent to Elm's type declaration in JS.

norm : float -> float -> float

means that norm is a function which when given two float arguments would produce a float as a result. This is an operational reading, but the intention is for norm to "associate" triplets of floating point numbers using some governing rule expressed in code.

Declaring new type synonyms

type alias Measure n = n -> n -> n
norm : Measure float

Just like a function f applied on a value a produces another value via the application expression f a, a "type constructor" T when given a "type argument" a produces a new type via the type expression T a. Just like with functions, you're not limited to a single argument.

Records

var x = {
    key1: "value1",
    key2: "value2"
};

is written as

x = { key1 = "value1"
    , key2 = "value2"
    }

However, the records are not mutable in Elm. To "update" a record, you make a new record with one the fields taking on a different value. For example,

x2 = {x | key2 = "VALUE2"}

... which is to be read as "x2 is the record x but with key2 having the value "VALUE2"".

The type of such a record is expressed as -

{key1 : ValueType1, key2: ValueType2}

Enumerations

Again, no JS equivalent. You can define enumerated types in Elm like with these examples -

type DayOfWeek = Sun | Mon | Tue | Wed | Thu | Fri | Sat
type Either a b = Left a | Right b
type Maybe a = Just a | Nothing

The real utility of such enumerations comes when used in conjunction with case expressions. For example -

f : Maybe a -> Maybe a
f m = case m of
        Just x -> Just (x * x)
        Nothing -> Nothing

Data structures

Lists are written as [v1,v2,...,vn] - i.e. same syntax as JS arrays, but these are list expressions. All elements of a list must be of the same type and the list's own type is written as -

listOfNames : List string

If you want to make an array in Elm, use the Array module. These are persistent and immutable arrays implemented efficiently.

arr : Array float

Dictionaries that map keys to values can be created using the Dict module.

planetNames : Dict int string
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment