Hi, I'm Martin.Say Hi on Twitter: @martinklepsch

November 2015Om/Next Reading List

A small dump of things I read to learn more about Om/Next. Most of these I stumbled upon while lurking in #om on the Clojurians Slack.

Thinking in Relay

This is Facebook's high level overview for Relay. It explains the reasoning for colocating queries and how data masking allows developers to write components that are not coupled to their location in the UI tree.

Om/Next Quick Start

This is the official Om/Next quick start tutorial. It guides you through building a basic application with Om/Next and introduces the basic API for queries and mutations. After reading this you should have a rough idea what's being talked about in the next two reads.

Om/Next The Reconciler

Kovas Boguta who previously gave an Om/Next workshop with David Nolen wrote this introduction to the Om/Next reconciler. It covers the architectural role of the reconciler managing application state and communicating it to components. The reconciler also acts as an indexer of all components and, using their queries to build a depdency graph, knows when to update which components.

Om/Next Overview

Written by Tony Kay this overview covers many practical aspects of writing queries and mutations. Before it goes into the nitty gritty details howvever there is another short Problem → Solution section that nicely describes the concepts in Relay and Om/Next in prose.

Now put all those links into Instapaper/Pocket & enjoy reading!

August 2015Parameterizing ClojureScript Builds

Just like with most server side software we often want to make minor changes to the behaviour of the code depending on the environment it's run in. This post highlights language and compiler features of ClojureScript making parameterized builds easy peasy.

On servers environment variables are a go-to solution to set things like a database URI. In ClojureScript we don't have access to those. You can work around that with macros and emit code based on environment variables but this requires additional code and separate tools.

With ClojureScript 1.7.48 (Update: There was a bug in 1.7.48 goog-define. Use 1.7.107 instead.) a new macro goog-define has been added which allows build customization at compile time using plain compiler options. Let's walk through an example:

(ns your.app)
(goog-define api-uri "http://your.api.com")

goog-define emits code that looks something like this:

/** @define {string} */

The goog.define function from Closure's standard library plus the JSDoc @define annotation tell the Closure compiler that your.app.api_uri is a constant that can be overridden at compile time. To do so you just need to pass the appropriate :closure-defines compiler option:

:closure-defines {'your.app/api-uri "http://your-dev.api.com"}

Note: When using Leinigen quoting is implicit so there is no quote necessary before the symbol.

Under the hood

When compiling with :advanced optimizations the Closure compiler will automatically replace all occurrences of your defined constants with their respective values. If this leads to unreachable branches in your code they will be removed as dead code by the Closure compiler. Very handy to elide things like logging!

Without any optimizations (:none) goog.define makes sure the right value is used. There are two global variables it takes into account for that: CLOSURE_UNCOMPILED_DEFINES and CLOSURE_DEFINES. When you override the default value using :closure-defines the ClojureScript compiler prepends CLOSURE_UNCOMPILED_DEFINES with your overridden define to your build causing goog.define to use the value in there instead of the default value you defined in your source files.

For details see the source of goog.define.

July 2015ClojureBridge Berlin

About two weeks ago something awesome happened: the very first ClojureBridge workshop in Berlin. After months of planning things finally got real.

ClojureBridge Berlin in it's entirety.

ClojureBridge aims to increase diversity within the Clojure community by offering free, beginner-friendly Clojure programming workshops for women.

Many of you probably got the "news": there's a lack of diversity in programming communities. Many communities acknowledge this and have created initiatives to fix it. The Ruby community has RailsBridge (and more) and other communties equally do their part in improving our industries diversity situation. Inspired by RailsBridge the Clojure community established ClojureBridge and has organized more than 20 workshops worldwide since.

Why Diversity?

There are endless amounts of research why diversity is desirable but one of the reasons that seems most intuitive to me is that software is, after all, for humans. If we want to make great software for everyone then it can only be made by all of us and not by one priviliged monoculture.

ClojureBridge Berlin

ClojureBridge workshops consist of one evening installing required software (Friday) and a full day of actually learning things (Saturday). Besides some problems with our pizza delivery both days went really well. We had great vegan and vegetarian lunch on Saturday, fun ClojureBridge cupcakes and after the coffee machine broke on Friday people brought lots of coffee making equipment to the event on Saturday. You could say we had a little third wave coffee workshop as well.

We got some sweet cupcakes!

On Saturday we initially had 2-3 coaches that "didn't have a job" and we were afraid they might feel superflous but the need for some additional help quickly arised when some learners got ahead of the rest of their group. In the end we were very happy that we had the flexibility of not having assigned all coaches to groups. (We still had teaching assistants.)


At the end of the event we had a fantastic demo time. A great amount of learners showed their Quil creations, from an Santa Claus to stroboscopic rainbow animations. It was great to see how in the beginning everyone was shy to show their work but as more people did others felt encouraged to do the same.


This was the first time we organized such workshop in Berlin. We were lucky to be a big team of organizers (six people) which allowed us to distribute the work.

The feedback we got during and after the workshop has been very positive. About a third of the attendees have registered interest in joining project groups to keep learning. Obviously the more the better but even ten people is a nice outcome overall.


I'd like to take the opportunity to thank all of our coaches: Nils, Sean, Paulus, Jan, Johannes, Ben, Franziska, Luca, Txus, Kofi, Torsten, Tibor, Thomas, Stephan, Oskar, Kai & Matt thank you so much for being part of this. None of it would have happened without you!

Also I'd like to thank my fellow organizers for pushing through the finish line together and for just being an overall awesome bunch. Thanks Bettina, Malwine, Arne, Jelle & Nicola.

Last but not least I'd like to thank the companies that enabled ClojureBridge Berlin: Wunderlist, SoundCloud, GitHub, InnoQ, TicketSolve, Babbel & DaWanda. A special thank you in this regard to Andrei, who has done an exceptional job at hosting the event at Wunderlist!

ClojureBridge Berlin T-Shirts

If you'd like to be informed about upcoming workshops, follow @ClojureBerlin on Twitter. If you don't have Twitter you can also send me an email and I'll make sure you'll be notified :-)

June 2015Managing Local and Project-wide Development Parameters in Leiningen

Little tip. Long headline.

In any project there are often settings that are specific to the context the project is run in (think of an environment parameter) and then there are parameters that are specifc to the developer/workstation they're run on. This is a guide to separate these two things nicely in Leiningen-based Clojure projects.

So you have a project setup that uses environ to determine the context the project is run in (development vs. production).

; in project.clj:
(defproject your-app "0.1.0-SNAPSHOT"
  ; ...
  :profiles {:dev {:env {:environment "development"}}})

Now you also want to use environment variables (or anything else thats supported by environ) to store AWS credentials to access Amazon S3. You don't want to commit these credentials into version control, therefore you can't add them to project.clj. The way to go is to create a file profiles.clj in your project to store workstation specific information. Naively this could look something like this

{:dev {:env {:aws-access-key "abc"
             :aws-secret-key "xyz"
             :s3-bucket "mybucket"}}}

If you run your project with this profiles.clj you will be able to access your AWS credentials. You might also notice that (environ/env :environment) is nil. That wasn't intended.

The problem here is that Leiningen will override keys in profiles defined in project.clj if the same profile has also been defined in profiles.clj. To recursively merge Leiningen profiles combine them like so:

;; in project.clj:
(defproject your-app "0.1.0-SNAPSHOT"
  ;; ...
  :profiles {:dev [:project/dev :local/dev]
             :project/dev {:env {:environment "development"}}})

;; in profiles.clj
{:local/dev {:env {:secret-key "xyz"}}}

Now both, :envrionment and :secret-key should be defined when you retrieve them using environ.

This is largely inspired by James Reeves' duct Leiningen template.

April 2015Formal Methods at Amazon

I saw this paper being mentioned again and again in my Twitter feed. Basically not even knowing what "formal methods" really means I was intrigued by the claim that it's easy to read. And it has been.

The paper describes how Amazon used a specification language to describe designs of complex concurrent fault tolerant systems finding bugs and verifying changes in the process.

The specification language (TLA+) is not focus of the paper, rather the authors concentrate on describing benefits, problems and the path of adopting formal specification of system designs in an engineering organization.

TLA+, stands for Temporal Logic of Actions and "is especially well suited for writing high-level specifications of concurrent and distributed systems."

Reading how they use it at Amazon I'm under the impression that it works very similar to generative testing dumping a ton of basically random (according to some rules) data into a system and checking if the desired properties are maintained. Often the term "model checker" is used.

Download the original paper or a copy of it with some passages highlighted that I found particulary interesting.