Pre-West Interview: Bruce Hauman
Talk: Developing ClojureScript with Figwheel
Bruce Haumans's talk at Clojure/West is about Figwheel, his tool for compiling and auto-reloading ClojureScript in the browser.
Background
One of the characteristics of web development is that it is highly dependent on visual feedback. The various languages are loose enough in their semantics that it is hard to verify their correctness past how they look. Typically, you write some code then reload the browser to see the changes.
This can work, but each time you reload, you lose all of the Javascript state in the browser, which can make each change take a long time. Each time you reload, you have to reinstatiate the state, either manually or automatically. Figwheel solves this problem in a different way: whenever your ClojureScript file changes, recompile it and push it to the browser (over WebSockets). If you set the ClojureScript up right, your state will be preserved.
I have used Figwheel and it absolutely changes ClojureScript development. It's one of the first things I set up in a new ClojureScript project. This talk will explain how to work it into your workflow.
Read this introductory blogpost about Figwheel with a demo video.
About Bruce Hauman
Introduction
Bruce Hauman was gracious enough to give me an interview. He is giving a talk at Clojure/West about Figwheel, the ClojureScript autoreloader. The background for his talk is available, if you like.
Interview with Bruce Hauman
PurelyFunctional.tv: How did you get into Clojure?
Bruce Hauman: I was doing Rails work and I was really burnt out. I had heard of Clojure and ClojureScript through HN and I have always been a big lisp fan. My favorite programming books were the Little Schemer series, PAIP, and SICP. I rewrote the pattern matching macro in PLTScheme (now Racket) as a hygenic macro and was its maintainer for a brief time.
My friend Tobias Crawley (of Immutant) was using Clojure as well and speaking its praises.
Yeah so I was already a crazy lisp fan and the idea that I could develop front end stuff in ClojureScript absolutely captivated me, so I started with it.
I also have to credit Simple made Easy and Rich Hickey's other inspiring talks.
PF.tv: Why did you create Figwheel?
BH: A year ago, I was doing a lot of exploring with ClojureScript and at the time the REPL really didn't work. I would work really hard to get a REPL working and that work would be rewarded with an unstable REPL that just would freeze up at the worst time, so I gave up on it.
My motivation to write Figwheel was all about feedback. The process of repeatedly reloading the browser and manipulating a ClojureScript program into a certain state to test/verify wether a certain code section was behaving as expected was becoming absolutely intolerable. I really don't know how front end developers put up with this.
So I asked myself "Well what is the ideal experience here?." The answer was pretty clear: I want to see the effects of my code changes as soon as I save a file.
I started by doing a simple test. I reloaded whole files into the browser when they finished compiling. This brute force method worked surprisingly well. I had to think about the load time side-effects of my code more, but the feedback especially for GUI programming was absolutely awesome.
I look back now and realize I was really lucky. The Google Closure module system is very amenable to hot patching, this and ClojureScript's awesome incremental compilation made this process very straightforward. Lots of things could have made this much more difficult/impossible but everything was in place just waiting for me to put the pieces together.
PF.tv: What were some of the challenges creating Figwheel?
BH: The hardest part initially was hooking into lein-cljsbuild to get a fast reliable after compile hook. At the time, I didn't have any experience writing Leiningen plugins and also very little time working with Clojure itself, so the going was a little rough.
Iterating on the plugin was very time consuming because I didn't how to tap into the running process with nREPL. I ran "lein figwheel" over and over again and waited for the process to boot way too many times before I decided to learn a better workflow.
I feel like this stuff is arcane knowledge in the Clojure world. Folks talk about REPL driven workflows but as a newcomer its tough to ferret out the actual workflows themselves. Once you get it, you get it, but before then it's kinda hard to discover.
The next hardest thing was hacking the Google Closure module system defined in goog/base.js to accommodate live module loading. The hooks were there but I had to do a bunch a searching to find them. It turned out that a two line hack enabled live reloading with proper downstream dependency handling. Again, I felt like I got really lucky that things were designed this way.
After that it was smooth sailing until I got fed up with how editing macros (or any clj file on a cljs path) caused lein-cljsbuild to do a complete project recompile. This caused all kinds of havoc. I had to fix this. I wanted macro editing to be just as responsive as editing cljs files. This took a bunch of time but I am super happy with the result. Whenever I edit a macro live and think about the downstream changes being made, I'm damn impressed by the power that ClojureScript offers modern front end developers. Code "transformations" that you are defining live are being applied to your ru nning code base live in the browser!!! Dang! Think about all the design decisions that came together to make that possible. Impressive!
PF.tv: Anything else you'd like to share?
BH: I am really looking forward to ClojureWest, if people see me walking by please don't hesitate to hit me up.
There is hopefully going to be a Figwheel Unsession that will be more interactive and more technical, if people are interested they should add their twitter handle to the unsession page.
PF.tv: Where can people find you online?
BH:
- Blog: rigsomelight.com
- Twitter: @bhauman
- IRC: chat.freenode.net #clojurescript
PF.tv: If Clojure were a food, what would it be?
BH: Foie gras corn dog.