← Sean Lawrence

Vessel - Writing a Game in Elm

This week at Hacker School I started working with a language called Elm. The language's creator (Evan Czaplicki) was a resident during the week so I had the absolute best resource available to me while playing with it. The language is functional (based on Haskell, or so I'm told) and features Functional Reactive Programming, among other things. In other words, Elm would throw a lot of new concepts at my imperative brain.

Initially progress was slow. At the end of the first day all I had to show was a program that wouldn't compile. I made some gains the next day by talking to fellow students who were familiar with functional concepts and eventually paired with Evan for about an hour which helped immensely (special thanks to Brian as well - check out his Elm flappy bird clone). The end result was a "tunnel" type game much like the one that I used to play on my TI-83+ graphing calculator in high school. In all it took me about three days to go from zero knowledge to small functioning game.

Some Observations...

Elm's most distinguishing feature is Functional Reactive Programming. The general idea is that you can bring in variables that change (or don't) over time. For example, the mouse's x and y coordinates can be represented by the Mouse.position signal. As a user moves their mouse, its coordinate is pushed through the program. When these signals are pushed (that's probably not the best term) can be controlled by a function called sampleOn. At every sample the functions invoked by foldp get to work and begin to "update" the game state (I say update but what I really mean is a new state is created based on the existing state - it's immutable).

The foldp function was difficult for me to grasp initially. This function is similiar to foldl and foldr functions, but works over Signal inputs. My mental model of this concept is to imagine Signal inputs as an array, where only the first value is accessible. This value represented the latest "signal." Eventually I came to understand that the "p" in foldp stands for "past" which helped it make more sense. It probably didn't help that I was unfamiliar with the other "fold" functions as well and had to learn those too.

I began to start thinking functionally towards the end. This meant making sure each function had all the information needed via its args to do its job and thinking in terms of composing functions together rather than passing objects by reference into functions. In other languages you can get a way with modifying a global variable in a function without taking the time to refactor, eliminating referential transparency, and potentially introducing bugs in the future as complexity increases.

I do think Elm has exposed me to a different way to model and write a program. As I was working on the game, I almost inevitably had a working program if I could get it to compile. I think the key insight for me was that Elm was forcing me to face my ineptitude at the compile stage. If I made the game with javascript I would of encountered these bugs at runtime and I would undoubtedly have additional lurking issues related to stagnating and/or state changes due to side effects, resulting in situations I never predicted, finally creating abnormal behavior and/or crashes. When working with Elm, I didn't have to re-run the program often to find bugs. If there were problems encountered during runtime, it was more of the "my explosions don't look like explosions" and not some errant issue.

Going forward I believe it will not be difficult to adopt a more functional style in my javascript code. I have yet to read Functional Programming in Javascript but now I have a very good reason to. The topic used to feel imposing, but now it's a little less so.