I've been experimenting with Elm for the past few months and have come to really appreciate its style of programming. It is very similar to React in the sense that you can render modular components based on DOM events, but the functional style and syntactic sugar are a pleasure to work with. In this blog post I will guide you in building your first Slack inspired component.

By now you have probably heard about Elm, the statically typed, immutable, Haskell inspired, polite and helpful, functional reactive language for the web.

I've been experimenting with Elm for the past few months and have come to really appreciate its style of programming. It is very similar to React in the sense that you can render modular components based on DOM events, but the functional style and syntactic sugar are a pleasure to work with.

My favorite thing about Elm is that it is statically typed, yet type inferred. What that means is you can prototype quickly, and don't have to use type annotations, but the compiler will infer the types for you by flowing through your code and failing to compile when you did something wrong. This gives rise to Elm's best feature:

NO RUNTIME EXCEPTIONS!

This is a really big deal! After having written a fair amount of Elm it almost feels irresponsible writing JavaScript without this feature. Elm accomplishes this by forcing you to handle values that can be null before allowing you to compile your project. It also makes sure that you handle all potential values when using conditionals/pattern matching.

As you work with Elm its awesomeness unfolds before you, and you will learn interesting Computer Science concepts, particularly if you have never worked with Haskell or other functional languages. Although Haskell can be hard to learn, Elm is very pragmatic and approachable and can be used to replace both standalone JavaScript libraries and rich UI components. Elm also lends itself really well for game programming due to its rich HTML5 Canvas abstraction and input interaction using signals.

My reason for writing this blog post is that I was struggling with some of the more advanced concepts of Elm, namely Signals, Mailboxes, and Ports. I started writing a post about how to roll out your own Model View Update pattern in Elm without the StartApp but it was hard to start without an initial example, so I decided to write this post first to lead into the next one.

In this two-part blog post I will take you through building your first Elm component - a Slack inspired quick channel switcher (Cmd+k).

I chose this component because it was small, practical, and combined multiple Signals, namely HTML Signals and Keyboard Signals, making it an ideal candidate for introducing Signals and Mailboxes.

Elm uses a Model View Update architecture which dictates the way data flows through an Elm application. You can think of an Elm application as a stream of events which are converted into actions, which then calculate the new state and render HTML.

I like annotating my code with sections so that it is organized and I know where to look for things so I label it like so:

Now that we imported all of the HTML attributes it's time to write some Elm-flavored HTML.

Under the view section declare a view function, follow that function with a main function, the entry point for any component. For now we will just use it to call view so we can see the HTML we generated.

As the user is interacting with the component, a new "state" of the model will be calculated. For example, selectedChannel will start at -1 and as we press the arrow keys up and down it will change to 0, 1, 2 etc.. Elm creates that new model using the update function. Our update function will take an action and return a new version of the model with a small modification.

This makes it very convenient since you can look at the action type definition (see below) and immediately know what kind of transformations can happen to the model in this component.

That's because StartApp is passing a Mailbox address and the currently computed model to the view. Don't worry about understanding Mailboxes just yet, we will cover those in the second part of the tutorial. For now, to fix this error let's refactor our view function signature to the following, and add a type annotation while we are at it:

view : Signal.Address Action -> Model -> Html
view address model =

Now you should be able to compile but as you notice when you open index.html the component still does not filter the list. Next we will render the model and implement the search/filter functionality.

We created two new methods renderChannel, which renders an individual li representing a channel with the hash symbol (#), and renderChannels which uses a List.map to return a list of li elements. We then pass that list as the second argument of ul. Lastly, we call renderChannels from the view function, passing in the model.channels.

Note: If you are wondering about the <| operator: it is a reverse pipe and it means the result of everything on the right of that operator (until the closure) will be piped into the function to the left of the operator. It's just a way to avoid parens.

In the next post I will deconstruct some of the magic behind StartApp and show you how to build a version of this component with Signals, Mailboxes and Ports. This will allow us to add keyboard interaction and JavaScript interop.