Learning Clojure: Error messages

I started my recent Clojure talk by enumerating the “scary bits” for new users. The two I went into were the fundamentally different semantics, and that the doc strings for the core functions were succinct and exact, but not expansive in use cases.

There was one that I forgot to bring up, though: compiler error messages when there’s a problem with a macro call.

There’s been a lot of chatter on the topic this past week, since Colin Fleming gave a talk at Clojure/Conj on the subject focusing on how to improve them with grammars. The conversation has kept a positive focus on how to fix it, as opposed to piling negativity on the situation (go Clojure community!) but that does not mean we can expect to see a change right away.

I’d like to address how this might affect you if you’re just getting into the language, and what you can do about it.

git flow releases with ClojureScript

While we’re on the topic of Clojure being useful

I use git flow for all my projects. It’s relaxing to know that, even when you’re working solo, you have zero chance of screwing yourself over because - say - you need to make a hotfix but can’t because of a dirty master branch state.

In some projects like khroma I’ll use major/minor version for the release numbers. But in a lot of cases, like this very site, there’s no concept of a major or minor release - you just want to time-stamp each one. I may even need to start several releases a day.

I wrote a small ClojureScript helper to remove the chance of human error.

The Clojure learning curve

I love Clojure.

Once you have tried it and enjoyed its advantages, you just don’t want to go back. But those same qualities that make you love it can make it easy to forget that, for someone who’s first encountering it, Clojure can be a threatening, scary area far outside their comfort zone.

A few weeks ago I gave a talk at the Bucharest Functional Programming Meet Up. The title was Clojure All The Way Down, since my initial plan was to focus on how to program web applications completely in Clojure (both the browser client and back end), and what it brings to the table.

Two things happened as I prepared the talk.

Relevance - Preview release

I’m a tab-aholic

I normally do a search, start opening the tabs that seem interesting, and then as I flip through them, I end up opening even more links on tabs as they seem relevant. Next thing I know I have a huge mess of tabs, and it’s hard to remember which one I’ve read or which one is important.

Relevance is a Chrome plugin I wrote to help manage that.

Respecting early adopters

Perhaps the trickiest thing when developing an open source library is figuring out the balance between changes you feel are necessary, and respecting early adopters.

Take the case of khroma, the ClojureScript library for providing idiomatic access to the Chrome extensions API. It’s very much a work in progress, and I’m developing it to use on an extension of my own. The way I go about it is exposing functions and event handlers mostly as I need them, to avoid getting sidetracked into surfacing functionality for which I don’t have a practical use case right away.

However, when developing something organically, the question then becomes: where do you draw the line between unifying the way the APIs behave after adding functionality, and not breaking things for those very early users?

Using devcards for testing a ClojureScript Chrome extension


A few weeks ago I wrote a short piece about the available tools for building Chrome extensions in ClojureScript.

Among the tools I reviewed was khroma, a still very much work-in-progress ClojureScript library providing idiomatic access for the Chrome API. One of original comments I had was that khroma was still incomplete, and had some not entirely evident function names.

I have since taken up khroma development and begun extending and refactoring it. However, a question immediately came up: how do we go about testing it? Your first impulse might be to say “why, don’t we have cljs.test?”.

Yes, we do, but we can’t run these tests automatically from the command line: the APIs are only available when you’re running inside Chrome as an extension with the right permissions.

Moreover, I’d like to be able to provide usage samples and data review for the myriad of events you can hook up to, some of which aren’t easily testable because they depend on user input, or asynchronous inter-page communication. How to go about this, then?

Enter devcards.

ClojureScript and Chrome extensions

There’s not as much documentation on building a Chrome extension with ClojureScript, so I thought I’d document my findings on the current state of libraries.

Yes, you can of course build Chrome extensions with ClojureScript, as other articles have pointed out. It’s, after all, just Javascript underneath. There’s some set up involved, and the example given hew closely to the Javascript-way of doing things.

Below are some tools that can help you with a more idiomatic way of doing things in Clojure.

cljs-build configuration tip: prefer maps over a vector

If you look at the lein cljs-build sample project, you’ll see that it states:

; The :builds option should be set to a sequence of maps.  Each
; map will be treated as a separate, independent, ClojureScript
; compiler configuration.

If you look at the example right below that description, you’ll see that it is actually set as a map of configuration profiles with the configuration name as the key. So what gives?

ClojureScript vs. CoffeeScript for Processing sketches

DECEMBER 2015 UPDATE: I’ve run some tests with the latest ClojureScript and made some minor changes to the code, which significantly improved performance. Read this post for updated numbers. Keeping this post around for archival reasons.

The set up

This whole thing started not as a performance test, but as me experimenting with ClojureScript and Quil while reading Matt Pearson’s Generative Art. As such, it is not the most scientific of comparisons, and instead born out of my notes when exploring how to do sketches with ClojureScript for the web.

Consider the following example: