Last Updated: February 25, 2016
·
1.836K
· supersymmetry

Natural language-like expressions with Clojure macro's

Clojure is a beautiful language and with a little boredom, time and having language-prone fantasies in the air tonight, somehow I cooked up a little fun display of macro's. In Clojure there are a gazillion ways to do stuff so don't flame me (or do - dun care :) but it's not intended as anything really serious nor am I a very big master of these higher arts. I should however post some stuff more often so here's a little first piece.

No external dependencies required but clojure.core namespace and symbols (or symbols have their fully qualified names referenced).

(def groups-of-flags
     {:status [:under-development :bugged :failure :status]})

(defmacro If [condition then consequent else alternative]
  (if (some #(= % (-> condition str drop-last
                                  clojure.string/join keyword))
            (get-in groups-of-flags [:status])) `'~consequent `'~alternative))

(and (If under-development? then good else bad)
        (If john? then good else bad)
        (If peter? then good else bad)
        (If bugged? then very-bad else good))

You can play around with those things near limitless and your only limits to about as far you go, are your own. But overall with the dynamic types, functional approach, local lexical scopes, powerful macro's and threading macro's, you can sure make some elegant expressions of near-human like writing style. Be it Clojure baby-english but still.

Of course you can always just use keywords (namespaced symbols) and just ignore the :. The capitalized If isn't by far conventional but more commonly you may find function/macro names of def+ of if-let which is about the same. Due to the syntax quoted unquote at '~consequent` and'~alternativewe don't get harassed for using unquoted symbols in our expressions, thethenandelsejust get ignored and I could have used_` as their replacement in the parameter definition block of the macro.