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.

Tip: Uncaught Invariant Violation

Uncaught Invariant Violation: onlyChild must be passed a children with exactly one child.

Are you using Reagent and Bootstrap with ClojureScript, and getting this error?

In my case, the cause was that I had a when inside an OverlayTrigger. Seems like a no-no. Further testing showed you can’t have an if either. Looks like OverlayTrigger can only wrap data, not something that might change.

In my case the solution was simple enough, once I figured out the cause: I just extracted when to wrap the OverlayTrigger, instead of the other way around.

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.

Relevance is now open source

I’ve released Relevance, my smart tab organizer for Chrome, under the MIT license. You can find the ClojureScript source code on GitLab, and the extension on the Chrome web store.

AWS Lambda, Clojure and ClojureScript

Introduction

In case you’re not familiar with them, AWS Lambdas are a fascinating idea - they are server functions you can create and run without first provisioning servers: you write your code, upload it, and pay only for the time that is executed.

There’s only one (somewhat minor) catch: given that there is no provisioned server capacity at all, the first time that you execute a lambda it has to be warmed up. The code stays live for a period of time after the first execution, but given Clojure’s start up time cost, I was wondering what effect that would have on a Clojure lambda.

ClojureScript performance revisited

Introduction

At the recent Thingmonk conference in London, I got to chatting about Clojure and ClojureScript. It’s an IoT event, so it was to be expected that the topic of performance on devices like the Tessel or Raspberry Pi would come up.

That got me thinking about the piece I wrote back in January about ClojureScript performance for Processing sketches. How much has ClojureScript performance improved since?

Let’s find out.

Use namespaced keywords for events

Introduction

If you’re using re-frame as your pattern for single-page applications in ClojureScript (and why wouldn’t you?), then you are defining your events and handlers using keywords.

These are a prime example of when Clojure’s namespaced keywords come in handy.

cljsbuild configuration for Chrome extensions

The problem

You’ve written your Chrome extension in ClojureScript, whether using Khroma or any other alternative. You have a background script, maybe some content script that gets run on pages, maybe some code for a management UI. Everything’s fine on development, but when you’re ready to release and want to apply some optimizations, everything gets bundled together into a single file. Not only you end up with a larger JS that gets loaded multiple times, but your initialization code starts tripping over each other.