Introduction to Elm
But let's go back to basics. First things first! Everybody loves a good Hello World.
[gist id="e6ff84252fb67bca0957" file="Hello.elm"]
>> elm make Hello.elm --output=app.js
And embed this file in your index.html like so:
The only thing to watch out for is that Hello.elm must have a module declaration at the top of the file. In this case, it would have to be module Hello where. This is needed because we're using the module name to initialize the app. The Elm component can then send/receive values from the rest of your application using Elm's Ports system.
Alternatively you can launch the Elm app fullscreen like so:
Documentation and Partially Applied Functions
One of the things that threw me when I first started looking at Elm documentation was the way method signatures are written. For example, take a look at the method signature for the repeat function in the String module:
>> repeat: Int -> String -> String
We can kind of infer what the function does: it takes in an Int and a String and returns the String repeated Int times. However, there is no distinction between the separators of input and output values: an arrow is used for both. It is implicit that the last value in the method signature is the type of the return value. There is actually a really good reason for this and it is to do with partially applied functions. Here's the String.repeat function in the Elm REPL:
And this is the same function but with an intermediate step where we create a partially applied function:
Notice that at each step, we get a printout of the current method signature and it goes from
>> Int -> String -> String
>> String -> String
Partially applied functions are supported in plenty of languages, but there is something really nice about having the method signatures actually written in a way that encourages actually understanding and using them.
This is the core feature of Elm. This is what makes the language so neatly reactive.
[gist id="d4ca611a48700e32ef76" file="Window.elm"]
The above code listens to the Window.dimensions Signal which broadcasts a tuple of the window width and height in pixels. The area function is applied to this these values and the result displayed in the browser. You can try this in the online editor. Resize the window and see the value dynamically update. Yay.
Side note: method signatures in Elm are actually optional! The above code would still work if I removed them, however once you include them, the Elm compiler will check that they match what the function does and not compile if there are any discrepancies.
Mailboxes are basically "signals that have an address you can send messages to". You can use them for reacting to UI events.
[gist id="cf8b199dc181001c18f9" file="Mailbox.elm"]
Here, I have defined a Mailbox for a String, and an Input field with essentially an onChange event handler. Whenever the text content of the input field changes, I call an anonymous function which passes the changed text into the Mailbox address. This same value is printed out to the page in the paragraph below.
So... the future?
"Should I write my next eCommerce site in Elm?" ... I think we're not quite there yet. But I it has huge potential. In fact, integrating Elm into an existing React/Flux application has been done before with huge success! The article also includes a tutorial on how to port a store from the Flux TodoMVC example to Elm.
Writing Elm is fun. It's a bit of a challenge as the online community is very small still (Googling for a "common" Elm problem will usually not get you to a solution). On the plus side, Elm compiler preemptively picks up on any runtime errors so you'll never see undefined is not a function ever again. I'd say that alone makes it worth giving it a go.
And if you like it, come to our special Elm edition of Functional Programming for the Web with Evan Czaplicki who will perhaps convince us why we should write our next eCommerce site in Elm.