It’s possible in Clojure to make your record data types implement the interface clojure.lang.IFn – and doing so means that you can use them directly as a function in normal Clojure code.

Example:

(defrecord Func [f x] clojure.lang.IFn (invoke [this arg] (f x arg)) (applyTo [this args] (apply f x args))) ((->Func + 7) 1) => 8

I’m still not totally sure whether this trick is a good idea – it might be considered to be “complecting” functions and data in a way that is unidiomatic.

Nevertheless I decided to try implementing this in Clisk and is certainly makes the DSL more expressive – now you can use any Clisk object as a function, and compose them as needed to transform other functions.

This lets you do things like:

(show (adjust-hue plasma (vplasma plasma)))

Quite pretty!