My experience upgrading to Elm 0.19

Elm is unstable, so upgrading to the next version can be painful. Here’s what I needed to do to upgrade from 0.18 to 0.19.

  • Replace elm-package.json and tests/elm-package.json with elm.json – e06f5a1728
  • Switch to the new elm-testb964b7c7a
  • Re-arrange Main, and how we call it from JavaScript – 0c118c49f
  • Stop using eeue56/elm-all-dict (since it’s not ported to 0.19 and porting it looked hard due to a lack of Debug.crash) – fe100f256
  • Replace toString with String.fromX or Debug.toString – 9e78163d0a3
  • Stop “shadowing” names by making new variables with the same name as another in the scope – 9688a621de
  • Adapt to the changed function – b991ab4f
  • Stop using Debug.crash – f98a70ad1
  • Adapt to the changes in the Regex module – 856762a4
  • Stop using tuples with more than 3 parts – 472c0bb7

The lack of Debug.crash is really, really painful, especially for a library like eeue56/elm-all-dict that has lots of invariants that are hard or impossible to enforce via the type system. On the other hand, if Elm can give a hard guarantee that there will be no runtime errors, this seems pretty cool. The problem is that some code may well have to return the wrong answer silently, instead of crashing, which could be much worse than crashing in some use-cases.

I was annoyed by the lack of more-than-3-part tuples, but even as I did the work to change my code, I saw it get better, so it’s hard to argue with.

The hardest part to work out was how to run the tests. Fortunately the tests themselves needed almost no changes. I just needed to do this:

rm -r tests/elm-stuff
rm tests/elm-package.json
sudo npm install -g elm-test@0.19.0-beta8
elm-test install

My next job is to check out the –optimize compiler flag, and the advice on making the code smaller and faster.

Writing a unit test in Elm

Series: Snake in Elm, Elm makes me happy, Elm Basics, Elm Unit Test

I’ve been having fun with Elm programming recently. Elm is a replacement for JavaScript that is pure functional and highly practical.

Here’s how to go from nothing installed at all to writing a unit test that passes, in just over 10 minutes.

The source code is here:

Mousedown events delayed or sluggish on mobile

I am learning about Elm and web apps by writing a little game called sootl.

It’s all SVGs animated with requestAnimationFrame(), and you control your player by clicking or touch the screen.

Everything seemed good on desktop browsers, but on mobile it took an age for the mousedown event to trigger when you touched.

Update: Thanks to @zatnosk on for letting me know there is a better way: 300ms tap delay, gone away. Short answer: add a <meta name="viewport" content="width=device-width"> tag inside your <head> tag.

It turns out that under certain circumstances, some mobile devices wait after the first touch happens to see whether you are going to swipe before they emit the mousedown event.

So, the short answer was to listen for touchstart events as well as mousedown ones. In Elm that looked like this change: e77e055e470c38489657ecaf5edc54a4e5f85782.

Elm resizeable SVG canvas filling the screen

I am toying with writing an SVG-based game in (exciting-looking JavaScript-replacement) Elm, and I wanted an SVG that filled the whole screen and resized when the screen resized. I found it harder than I expected, so here is what I came up with for your information and comment.

Try the demo.

Because I was using Html.App.programWithFlags I was not able to shortcut the process and use just elm-reactor – I needed to create an HTML file and compile my code with elm-make.

index.html sets up a full-screen app and passes in the window size:

    <meta charset="UTF-8"/>
    <script src="sootl.js"></script>
        html, body, svg
            margin: 0px;
            padding: 0px;
            border: 0px;
            overflow: hidden;
var app = Elm.Main.fullscreen(
        width:  window.innerWidth,
        height: window.innerHeight

elm-package.json requires the Html, Svg and Window packages:

    "version": "1.0.0",
    "summary": "Stay out of the light!",
    "repository": "",
    "license": "GPL2",
    "source-directories": [
    "exposed-modules": [],
    "dependencies": {
        "elm-lang/core": "4.0.5 <= v < 5.0.0",
        "elm-lang/html": "1.1.0 <= v < 2.0.0",
        "elm-lang/svg": "1.1.1 <= v < 2.0.0",
        "elm-lang/window": "1.0.0 <= v < 2.0.0"
    "elm-version": "0.17.1 <= v < 0.18.0"

Main.elm contains the Elm code, which starts off with the window size from JavaScript, and then listens to resize events using the Window module.

import Html exposing (Html)
import Html.App exposing (programWithFlags)
import Svg exposing (..)
import Svg.Attributes exposing (..)
import Window

type alias Flags =
    { width : Int
    , height : Int

type Msg = Resize Int Int

type alias Model =
    { screen :
        { width : Int
        , height : Int

init : Flags -> (Model, Cmd Msg)
init flags =
        { screen =
            { width = flags.width
            , height = flags.height
    , Cmd.none

view : Model -> Html Msg
view model =
        sw = model.screen.width  - 0
        sh = model.screen.height - 0
        [ width  <| toString sw
        , height <| toString sh
        [ rect
            [ x "0"
            , y "0"
            , width (toString model.screen.width)
            , height (toString model.screen.height)
            , fill "#eeffee"
        , text'
            [ x <| toString <| sw / 2
            , y <| toString <| sh / 2
            , fontSize <| toString <| sh / 10
            , textAnchor "middle"
            [ text
                ((toString model.screen.width)
                ++ ", "
                ++ (toString model.screen.height))

update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
    let m =
        case msg of
            Resize w h -> {model | screen = {width = w, height = h}}
        (m, Cmd.none)

subscriptions : Model -> Sub Msg
subscriptions model =
    Window.resizes (\size -> Resize size.width size.height)

main =
     { init = init
     , view = view
     , update = update
     , subscriptions = subscriptions

I installed all the packages with:

elm-package install

Then I compiled the code with:

elm-make --output=sootl.js Main.elm

Now I launched elm-reactor:


And navigated my browser to http://localhost:8000/index.html to see it working.

Elm Basics Video

Series: Snake in Elm, Elm makes me happy, Elm Basics, Elm Unit Test

A lot of the documentation about the new language I am really excited about, Elm focusses on the Elm Architecture and the ideas of Functional Reactive Programming, and while those are the fundamental reasons I am interested in Elm, I found myself stuck on the syntax quite often.

So, in this video I review almost all the syntax and basic ideas you need to be able to read and write Elm code, treating it as a general programming language.

Update: forgot to add the slides – here they are:
Slides: Elm Basics