November 14, 2014
Summary: Elm is an exciting FRP language. I implemented the FRP part in Clojure using core.async.
I like to read research papers. I have ever since I was in high school. I've always wanted it to be pretty easy to just translate the pseudocode for an algorithm for a paper and then have it working without any trouble.
Of course, this rarely happens. Either the pseudo-code leaves out important details, or it's expressed in terms that are not available abstractions in any language I know. So then I am left to puzzle it all out, and who has the time?
A few months ago I read the fantastic thesis by Evan Czaplicki where he introduces Elm. It includes a novel way to express asynchronous Functional Reactive Programming (which he calls Concurrent FRP) and a way to express GUI layouts functionally.
I highly recommend the thesis. It is very clear and readable, and points you to valuable resources.
The reason I was reading it was because I think FRP has a bright future. It's definitely got potential for simplifying the way we write interactive applications. I wanted to learn how it works so that I could build bigger castles in the sky.
Elm FRP is pretty cool. It is, first of all, very few parts. You build bigger abstractions from those small parts. It is built so that events trickle through the graph in order. In other words, they're synchronized.
But the other interesting thing is that sometimes you don't want things to be synchronized. What if one of the calculations takes a long time? You don't want the GUI to stop responding to mouse events while that slow thing is happening. Elm lets you segment the graph into different subgraphs that can propagate concurrently.
Seriously, just read the thesis.
While I was reading it, I got to this page where he lays out all of the FRP functions in Concurrent ML. It's not uncommon for entire Computer Science theses to be written, passed, and published without a line of runnable code. But here it was, in real code (no pseudocode). I don't know ML, but I do know Haskell, which is related. And I started puzzling through it, trying to understand it.
By flipping between the text and the code, I got it. And then I realized: everything I needed to write this was in Clojure with core.async. So I got to work.
It took a while of playing with different representations, but I got something I can use and that is pretty much a direct translation of the Concurrent ML code from the thesis. I toyed with some deeper factorizations, but I think they only muddy what's going on. And it runs in both Clojure and ClojureScript. It's available on Github.
And, of course, I needed to test my creation, so I ported the Mario example from the Elm website. You have to click on it to start it. Use the arrow keys to walk left/right and up to jump. It captures your keystrokes. Click outside of the box to get your scrolling keys back.
The code for Mario.
Now, I didn't write all of the cool GUI stuff from the second part of the thesis. I was learning Om so I decided to use that. That's why that part is so long. Writing Om components is basically as long as writing HTML + CSS.
And Elm is a language built around these FRP abstractions, so a lot of the signals are built in. I had to write event handlers to capture the mouse clicks and keyboard events. But right in the middle of mario.cljs, you'll see a very straightforward translation of the Mario example from Elm.
There are a few differences between the Elm version and the Clojure version. Clojure is untyped, so I was able to eliminate a channel used only to carry an input node id. That instead is passed along with the message on a single channel.
Also, I added a node type called "pulse" which I use for emitting time deltas for calculating physics. I'm not sure if Elm internally does something similar for its timers but it seems like the correct solution. The trick is you want to emit a zero time delta while other events are firing, and an actual time delta when the timer ticks.
Finally, instead of the graph being global as in the thesis, it's all tied to an "event stream", which is where you send the events which get channeled to the correct input signal. You can have multiple event streams and hence multiple graphs.
The implementation is very straightforward. You have to know the basics of Clojure core.async, plus mult
and tap
. core.async brings Clojure a new set of abstractions that let us tap into more research and learn from more languages. And that makes me happy :)
If you'd like to learn core.async, I have to recommend my own video course LispCast Clojure core.async. It teaches the most important concepts from core.async using story, animation, and exercises. It is no exaggeration to say that it was the most anticipated Clojure video when it came out. Go check out a preview.
You might also like
April 15, 2015

Introduction
James MacAulay is the next interview participant. He is giving a talk at Clojure/West about Functional Reactive Programming with the clojure library Zelkova. The background to his talk is available, if you like.
Interview with James MacAulay
Nola: How long have you been doing clojure and how did you get into it?
James: I've been writing Clojure in my spare time on-and-off for about three years.
In late 2011 I was on a small team developing a JavaScript MVC framework, and we had this problem of managing state in the browser over long periods of time. Our response was to let mutation happen all over the place and keep track of it all with a network of observed properties. It felt fun and empowering at first, but unfortunately it resulted in systems that were very difficult to reason about.
At some point I looked at the system and realized that all it needed to do was handle external events one at a time, and render some views based on those events. It was all starting to look like one big function to me...so I figured I should give a serious look at what functional programming was all about. Clojure had some really compelling answers to the questions I had, and soon I was hooked.
Nola: Any suggestions for someone wanting to dive into clojure?
James: If you're coming from an Object-Oriented background, take your time just getting used to writing different kinds of functions without relying on mutable state. The more you do it, the more fun it is, and it ends up being a really valuable habit to have when writing software in any language.
Nola: What languages did you do before clojure?
James: Mainly Ruby and JavaScript. In university it was Java more than anything else, but we were exposed to a number of other languages in smaller doses: Scheme, Prolog, C, x86 Assembly are the ones I'm most thankful for. When I first got interested in functional programming I dug into Haskell for a bit before Clojure really grabbed me.
Nola: Your talk is about Zelkova which is heavily inspired by Elm. Have you done much with Elm or implemented Functional Reactive Programming in other languages?
James: I first really got the Elm bug at Strange Loop 2013, where I saw Evan Czaplicki live code the Mario demo first-hand. I started playing with both Elm and Bacon.js, a JavaScript FRP library. Last summer I decided to try my hand at implementing FRP in Clojure, and figured I should read Evan's thesis to see how Elm works. I hadn't implemented any kind of FRP before, but Clojure seemed like a great language to do it in.
My experience with the Elm thesis was very similar to the one Eric Normand described having at around the same time – the code in the paper was just begging for a core.async implementation. I started hacking away, and learned a ton about both Elm and core.async in the process.
At Strange Loop 2014, I got to meet Evan and we had a really great chat about Elm and my work on porting its FRP system to Clojure and ClojureScript. He encouraged me to share my work and clarified a lot of things for me, and I've been poking away at Zelkova ever since.
Nola: What is the average airspeed velocity of an unladed Clojure REPL?
James: I try not to throw my laptop across the room when I get frustrated :)
Nola: Thanks for the interview. It was very informative.
This post is one of a series called Pre-West Prep, which is also published by email. It's all about getting ready for the upcoming Clojure/West, organized by Cognitect. Conferences are ongoing conversations and explorations. Speakers discuss trends, best practices, and the future by drawing on the rich context built up in past conferences and other media.
That rich context is what Pre-West Prep is about. I want to enhance everyone's experience at the conference by surfacing that context. With just a little homework, we can be better prepared to understand and enjoy the talks and the hallway conversations.
Clojure/West is a conference organized and hosted by Cognitect. This information is in no way official. It is not sponsored by nor affiliated with Clojure/West or Cognitect. It is simply me (and helpers) curating and organizing public information about the conference.
You might also like
April 15, 2015
James MacAulay's talk at Clojure/West is about Zelkova, his Functional Reactive Programming library.
Background
Zelkova is a Functional Reactive Programming (FRP) library inspired by the Elm FRP model. FRP is a model for building composable "signals" that maintain the state of the system over time. The talk promises to show us how to use it with Om to create interactive applications.
There are many resources out there, but I recommend this talk about Functional Reactive Programming in Elm by Elm's creator Evan Czaplicki. It shows the possibilities of FRP. His thesis, which describes the basic constructs of Elm, is surprisingly approachable. I recommend that highly. Also, James MacAulay himself did a Papers We Love presentation about it, which is worth watching.
GitHub - Twitter

This post is one of a series called Pre-West Prep, which is also published by email. It's all about getting ready for the upcoming Clojure/West, organized by Cognitect. Conferences are ongoing conversations and explorations. Speakers discuss trends, best practices, and the future by drawing on the rich context built up in past conferences and other media.
That rich context is what Pre-West Prep is about. I want to enhance everyone's experience at the conference by surfacing that context. With just a little homework, we can be better prepared to understand and enjoy the talks and the hallway conversations.
Clojure/West is a conference organized and hosted by Cognitect. This information is in no way official. It is not sponsored by nor affiliated with Clojure/West or Cognitect. It is simply me (and helpers) curating and organizing public information about the conference.
You might also like