Fast is not enough

I’ve been advising a startup on the data transformation space. As part of this, we re-wrote the core engine in Clojure. The new version is, at the worst case, 16 times as fast in the same hardware, and in some cases over 200 times faster. And it does it with a fraction of the lines of code.

We did this in under 3 months of part-time work. We couldn’t focus our entire attention on it, as we had other concerns as well - I was involved with general team and management tasks, and the second developer was helping on other internal projects as well. To further raise the bar: we had to keep it functionality-compatible with the current version, so I had to get acquainted with the existing feature set, and it was the other developer’s first Clojure project.

Clojure made our lives so much easier. But this is not a post about why Clojure is cool.

Reading Clojure, part 2

Welcome back

Have you gone over the fundamentals on Reading Clojure? Did you shake off that preconception that there’s some magic syntax to declaring and evaluating things beyond the list?

Great! Let’s now go over other things you might encounter when looking at a random source file. I’m first going to give you an overview of types and related things. After it, we’ll then we get into the good stuff like going over a project, and the weird stuff like ->, ->>, #, the quote and other squiggles.

Reading Clojure

Preamble

Back in early December I held a Clojure workshop for the Bucharest Functional Programming meet up. Having to explain the language to developers who were completely new at it was an interesting experience. I decided to start from the ground up: how to even read the blasted thing.

HTML parsing in Clojure

Once again I’m doing a personal project that requires me to do some HTML parsing. If you have had to look at it, the landscape of Clojure HTML parsing libraries seems to be littered with dead projects.

Let’s look at the options.

Deploying a Clojure application from Gitlab CI to Heroku

Now that we have our Clojure application tested every time we push it to Gitlab, let’s configure another stage to deploy it to Heroku.

This assumes that:

  • Anything you merge to master is ready to deploy,
  • You have your Heroku API key handy, and
  • You already have a Heroku app configured, with all the necessary environment variables.

There’s two ways we can do this.

Using Gitlab CI with a Clojure project

Gitlab allows you not only to have free private repositories, but also to test them using free runners. These can run automatically, on push, for any branch or tag.

I keep a few private repositories with them, for personal projects and small experiments. I decided to give Gitlab CI a shot for a PostgreSQL-backed Clojure project.

There’s a basic example on the Gitlab CI repository. It gets and installs lein, which isn’t necessary. Instead, we’ll build use the clojure:lein Docker image.

Clojure, Cursive and Emacs

J. Pablo Fernández has recently posted a piece with the incendiary title of “Emacs is Hurting Clojure“.

I disagree with the idea behind the title, but then again, he seems to do so himself. He promptly clarifies:

Stop abstracting early

When I started working with Clojure, I wanted everything to be Clojure.

HTML? Vectors through Hiccup.
Configuration? Clojure maps.
SQL queries? Clojure lists.

After all, I might one day need to take advantage of Clojure’s functional abstractions to… um… well… I might need it, right?

Learning Clojure Fast

There have been several questions floating lately to the effect of “How do I get started fast?” or “What’s the bare minimum I need to know to get hired?”.

In case you’re wondering how to do that… you’re not going to like this answer.

ClojureScript tip: mind the Clojure version

Updated the ClojureScript version, and now you’re getting build errors? Check the Clojure version.

If you do an upgrade through lein ancient update, it will not upgrade the Clojure version. But if you have a ClojureScript dependency, it will be upgraded, and you may run into a case like this when building:

No such var: string/index-of, compiling:(cljs/source_map.clj:260:54)

I got this error when going from ClojureScript 1.8.34 to 1.9.93. I wasn’t using index-of directly, which is a Clojure 1.8 function… but ClojureScript was.