Artwork . Games

The Elm Platform

March 2, 2016

There are many existing guides about how to make use of the Elm language, architecting an Elm web application, or detailing standard packages. But what if you are a seasoned Javascript developer relying on tools like npm and gulp for development; how can you accomplish the same tasks when working with Elm?

Platform

If you are on OSX or Windows, you may have already installed the Elm platform from one of the installers. There is also an official npm package which makes it easy to install and update elm from the command line, by running npm install -g elm.

You now have an easy to use binary called elm with a handful of commands.

Elm Platform 0.16.0 - a way to run all Elm tools

Usage: elm <command> [<args>]

Available commands include:

  make      Compile an Elm file or project into JS or HTML
  package   Manage packages from <http://package.elm-lang.org>
  reactor   Develop with compile-on-refresh and time-travel debugging
  repl      A REPL for running individual expressions

You can then further dig into each command by adding the –help flag.

So, for example, if you want to know more about how the repl works, you can use this command:

elm repl --help

elm repl

When working with Javascript, one of the greatest tools at your disposal is the read eval print loop. Whether you are using the developer console in the browser, or the node environment in the terminal, having the ability to try out code interactively, printing values to the console, and exploring an API make it easy to experiment.

Elm provides you with something quite similar to the elm-repl tool. It is only available from the command line, but it can be a handy environment to explore the language, especially when you are first starting out.

Once you run the command elm repl, an interactive environment opens where you can type in Elm expressions and definitions.

> 1 + 1
2 : number

> "hello" ++ "world"
"helloworld" : String

You can do the same with definitions and ADTs.

> fortyTwo = 42
42 : number

> f n = n + 1
<function> : number -> number

> f 41
42 : number

> factorial n = \
|   if n < 1 then 1 \
|            else n * factorial (n-1)
<function> : number -> number

> factorial 5   
120 : number

> type Either a b = Left a | Right b

> case Left 32 of \
|   Left n -> 2 * n \
|   Right m -> m + 1
64 : number

You can also import libraries reachable from the directory where elm-repl is running, including standard libraries.

> import String

> String.length "hello"
5 : Int

> String.reverse "flow"
"wolf" : String

elm package

The npm command is a powerful tool that can do many things, but the first step in javascript development is to run npm init to setup your project. You end up with a package.json file.

{
  "name": "mylib",
  "version": "1.0.0",
  "description": "My awesome lib.",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "Me",
  "license": "ISC"
}

At this point, the project does not have any dependencies, but we can add one by using the npm install command.

npm install --save lodash

The following will add a section to the package.json file and download the library into a node_modules directory.

  "dependencies": {
    "lodash": "^4.5.1"
  }

A similar tool for Elm is called elm-package. To initialize a new elm project in an empty direction run the command:

elm package install

The tool will generate a default elm-package.json, which already contains a dependency on the elm-lang/elm-core package, and then downloads the library into an elm-stuff directory. As you can see, the process is very similar to the typical node process detailed above.

Feel free to open and edit the file. The fields are going to seem very familiar to the package.json in a node project.

{
    "version": "1.0.0",
    "summary": "helpful summary of your project, less than 80 characters",
    "repository": "https://github.com/user/project.git",
    "license": "BSD3",
    "source-directories": [
        "."
    ],
    "exposed-modules": [],
    "dependencies": {
        "elm-lang/core": "3.0.0 <= v < 4.0.0"
    },
    "elm-version": "0.16.0 <= v < 0.17.0"
}

You can also add dependencies with the elm-package install command. There is even a website like npm.js where you can search and browse for elm packages.

A useful package is ‘evancz/elm-HTML,’ which adds support for building HTML from Elm code. Let’s add it to our project.

elm package install evancz/elm-html

The tool will prompt you to add the dependency to elm-package.json and download the package to elm-stuff. Feel free to browse its documentation to see how you can make use of it in your project.

You can also use the elm-package tool to inspect changes between package versions. Say you know a new version of evancz/elm-html has come out, but you are not sure if you want to update. You can see what has changed between versions using the diff command:

elm package diff evancz/elm-html 4.0.2 5.0.0

The command will show you all of the changes from version 4.0.2 which you have and version 5.0.0 which you would like to have. The output should give you a basis for deciding if you should update.

Now you can manually update the version bounds in the elm-package.json file and run:

elm package install evancz/elm-html 5.0.0

If Elm detects problems with your new version constraints, it will provide you errors and instructions for how to fix the issue.

elm make

The build tool for Elm projects is elm-make, which will compile elm files to javascript or HTML that you can use in your web application.

Using the project that we created in the elm package section, create a Main.elm file and add the following code.

import Html exposing (text)

main =
  text "Hello, World!"

Building this project is straight forward.

elm make Main.elm

By default, elm-make will output an index.html file that you can load up in your browser right away. If you would like to generate a javascript file that you can add to your HTML file, add the --output option.

elm make Main.elm --output main.js

The elm-make project is designed to work with elm-package, so it will automatically pick up the third party packages you have installed. In fact, when you run the elm make command, if the dependencies listed in the elm-package.json file have not been downloaded, elm-make will call elm-package to prompt you to install them.

elm reactor

The Elm Reactor is an interactive development tool that makes it easy to develop and debug Elm programs.

elm reactor

Running the reactor in the directory of your project will serve it up at http://localhost:8000, which you should navigate to in your favorite browser. You should now see a listing of all the files in the project. Clicking on the link named Main.elm will let preview your app.

If you navigate back to the editor with Main.elm in it and edit the file, for example changing “Hello, World!” to “Hello, ElmCast!”, elm-reactor will recompile in the background. Refresh the browser to see your changes.

The reactor also provides an interactive debugging environment. If you navigate back to localhost:8000, notice the wrench icon to the left of the Main.elm entry. Clicking that button will load your elm app for debugging. We will explore the features of this tool in a later article because it depends on diving deeper into the Elm language to truly appreciate.