Open-source Bundling

Cast your mind back to the halcyon days of the late ’90s. Windows 95/98. Internet Explorer 4. Before you laugh, consider that IE4 included some pretty cutting-edge technology for the time: Dynamic HTML, TLS 1.0, single sign-on, streaming media, and “Channels” before RSS. IE4 even pioneered — unsuccessfully — the idea of “web browser as operating system” a decade before Google Apps.

But if you remember anything about IE in the ’90s, it’s probably the word bundling. United States v. Microsoft centered on the tight integration of IE with Windows. If you had Windows, you had to have IE. By the time the lawsuit reached a settlement, IE was entrenched as the dominant browser.

Fast forward to the present. What an enlightened age we live in. Open-source has won and the browser market has fragmented. Firefox broke the IE hegemony, and Chrome killed it. The web browser really is an operating system.

But if you look around at software today, “bundling” is still with us, even in open-source software, that champion of choice and touchstone of tinkering.

Continue reading →

How to Name Clojure Functions

This is a guide on naming Clojure functions. There are exceptions to every rule. When you’re defining something based on natural language, there are more exceptions than rules. I break these rules more often than I follow them. This guide is just a starting point for thinking about how to name things.

Pure functions

Pure functions which return values are named with nouns describing the value they return.

If I have a function to compute a user’s age based on their birthdate, it is called age, not calculate-age or get-age.

Think of the definition: a pure function is one which can be replaced with its value without affecting the result. So why not make that evident in the name?

This is particularly good for constructors and accessors. No need to clutter up your function names with meaningless prefixes like get- and make-.

Don’t repeat the name of the namespace

Function names should not repeat the name of the namespace.

(ns products)

;; Bad, redundant:
(defn product-price [product]
  ;; ...
  )

;; Good:
(defn price [product]
  ;; ...
  )

Assume that consumers of a function will use it with a namespace alias.

Conversions and coercions

I don’t much like -> arrows in function names, and I try to avoid them.

If the function is a coercion, that is, it is meant to convert any of several input types into the desired output type, then name it for the output type. For example, in clojure.java.io the functions file, reader, and writer are all coercions.

If there are different functions for different input types, then each one is a conversion. In that case, use input-type->output-type names.

Functions with side effects

Functions which have side-effects are named with verbs describing what they do.

Constructor functions with side-effects, such as adding a record to a database, have names starting with create-. (I borrowed this idea from Stuart Halloway’s Datomic tutorials.)

Functions which perform side-effects to retrieve some information (e.g. query a web service) have names starting with get-.

For words which could be either nouns or verbs, assume noun by default then add words to make verb phrases. E.g. message constructs a new object representing a message, send-message transmits it.

I don’t use the exclamation-mark convention (e.g. swap!) much. Different people use it to mean different things (side effect, state change, transaction-unsafe) so the meaning is vague at best. If I do use an exclamation mark, it’s to signal a change to a mutable reference, not other side-effects such as I/O.

Local name clashes

One problem I find is in let blocks, when the obvious name for a local is the same as the function which computes it. If you’re not careful, this can lead to clashes:

(defn shipping-label
  "Returns a new label to ship product to customer."
  [customer product]
  (let [address (address customer)
        weight (weight product)
        supplier (supplier product)]
    {:from (address supplier)  ; oops, 'address' clashes!
     :to address
     :weight weight}))

This is less of a problem when the functions are defined in a different namespace and referenced via an alias:

(defn shipping-label
  "Returns a new label to ship product to customer."
  [customer product]
  (let [address (mailing/address customer)
        weight (product/weight product)
        supplier (product/supplier product)]
    {:from (mailing/address supplier)  ; OK
     :to address
     :weight weight}))

If name-clashes become a problem, add prefixes to the function names, new- for constructors and get- for accessors. If you are bothered that this contradicts the previous section, re-read the first paragraph of this article.

Function returning functions

In general, I try to avoid defining top-level functions which return functions if I can write make the intent clearer using anonymous functions instead.

For example, writing something like this makes me feel clever:

(defn foo
  "Returns a function to compute foo of value."
  [option]
  (fn [value]
    ;;... do stuff with value ...
    ))

(defn computation
  "Does stuff with values."
  [option values]
  (->> values
       (map (foo option))  ; look at me!
       ;; ...
       ))

But it’s easier for someone else to read when the closure is created close to where it’s used:

(defn foo
  "Returns the foo of value"
  [value option]
  ;; ... 
  )

(defn computation [option values]
  (->> values
       (map #(foo % option))  ; I see what this does
       ;; ...
       ))

I allow an exception to this rule when returning functions is part of a repeated pattern. For example, the transducer versions of map, filter, and other sequence functions all return functions, but that’s a standard part of the language since Clojure 1.7 so users can be expected to know about it. Occasionally I discover a similar pattern in my own code.

When functions returning functions are not part of a repeated pattern but for some reason I want them anyway, I call them out with a suffix -fn, like:

(defn foo-fn
  "Returns a function to compute the foo of a value."
  [param]
  (fn [value]
    ;; ...
    ))

Clojure 2015 Year in Review

Another year, another year-in-review post. To be honest, I feel like any attempt I make to summarize what happened in the Clojure world this year is largely moot. Clojure has gotten so big, so — dare I say it? — mainstream that I can’t even begin to keep up with all the interesting things that are happening. But it’s a tradition, so I’ll stick to it. Once again, here is my incomplete, thoroughly-biased list of notable Clojurey things this year.

Continue reading →

An Opinionated Review of Clojure Applied

Why write a book about open-source software? (Not for the money. Trust me.) I’ve seen far too many “technical books” that merely regurgitate the documentation of a bunch of open source libraries. I’m happy to say that Clojure Applied, by my friends and colleagues Alex Miller and Ben Vandgrift, is not in this category. They sent me a free copy in return for review, so here it is.

Continue reading →

Clojure Don’ts: Lazy Effects

This is probably my number one Clojure Don’t.

Laziness is often useful. It allows you to express “infinite” computations, and only pay for as much of the computation as you need.

Laziness also allows you to express computations without specifying when they should happen. And that’s a problem when you add side-effects.

By definition, a side-effect is something that changes the world outside your program. You almost certainly want it to happen at a specific time. Laziness takes away your control of when things happen.

So the rule is simple: Never mix side effects with lazy operations.

Continue reading →

Clojure Do’s: Uncaught Exceptions

Some more do’s and don’ts for you. This time it’s a ‘do.’

In the JVM, when an exception is thrown on a thread other than the main thread, and nothing is there to catch it, nothing happens. The thread dies silently.

This is bad news if you needed that thread to do some work. If all the worker threads die, the application could appear to be “up” but cease to do any useful work. And you’ll never know why.

Continue reading →