Introduction to Code-Golf in Clojure

Code-Golf is the art of writing the shortest program in a given language that implements some given algorithm. It started in the 90’s in the Perl community and spread to other languages; there are now languages dedicated to code-golfing and StackExchange has a Q&A website for it.

In 2015, for example, I wrote a blog post showing how to write a JavaScript modules manager that fits in 140 chars (the maximum length of a tweet at that time).

4clojure is a well-known website to learn Clojure through exercises of increasing difficulty, but it has a lesser-known code-golf challenge which you can enable by clicking on “Leagues” in the top menu. If you check the code-golf checkbox, you then get a score on each problem that is the number of non-whitespace characters of your solution; the smaller the better.

The first thing you’ll note when code-golfing is that the reader syntax for anonymous functions is a lot shorter than using fn :

; 18 chars ( fn [ a b c ] ( * ( + a b ) c )) ; 13 chars # ( * ( + %1 %2 ) %3 ) ; 12 chars: -1 char because '%' is equivalent to '%1' # ( * ( + % %2 ) %3 )

Unfortunately you can’t have a reader-syntax function inside another reader-syntax one, so you often have to transform the code not to use anonymous functions.

for is a very powerful tool for that, because it allows you to do the equivalent of map , and a lot more, with no function:

; invalid! # ( map # ( * 2 % ) % ) ; 19 chars # ( map ( fn [ x ] ( * 2 x )) % ) ; 17 chars # ( map ( partial * 2 ) % ) ; 15 chars # ( for [ x % ] ( * 2 x )) ; Note that for this specific example ; the best solution uses `map`: # ( map + % % )

On some problems it can even be shorter than using map + filter :

; 31 chars ( fn [ x a ] ( map inc ( filter # ( < % a ) x ))) ; 26 chars # ( for [ e x :when ( < e a )] ( inc e ))

Some core functions are equivalent in some contexts and so the shorter one can substitute a longer one:

; 18 chars # ( filter identity % ) ; 14 chars # ( filter comp % ) ; 6 chars ( inc x ) ( dec x ) ; 5 chars ( + x 1 ) ( - x 1 ) ; 12 chars ( reduce str x ) ; 11 chars ( apply str x ) ; 14 chars ( apply concat x ) ; 13 chars ( mapcat comp x )

When you must use a long function name in multiple places, it might be shorter to let that function with a one-letter symbol:

; 120 chars # ( clojure.set/difference ( clojure.set/union % %2 ) ( clojure.set/union ( clojure.set/difference % %2 ) ( clojure.set/difference %2 % ))) ; 73 chars # ( let [ d clojure.set/difference u clojure.set/union ] ( d ( u % %2 ) ( u ( d % %2 ) ( d %2 % )))) ; Note that for this specific example ; there is a 17-chars solution # ( set ( filter %2 % ))

Other tricks

Use indexed access on vectors:

; 15 chars ( first [ :a :b :c ]) ; 11 chars ([ :a :b :c ] 0 )

Use set literals as functions:

; 16 chars ( remove # ( = :a % ) x ) ; 14 chars ( remove # { :a } x )

Inverse conditions to use shorter functions:

; 15 chars ( if ( empty? p ) a b ) ; 12 chars ( if ( seq p ) b a )

Inlined code is sometimes shorter:

; 24 chars ( let [ p ( * 3 a )] ( if ( < p 5 ) a p )) ; 19 chars ( if ( < ( * 3 a ) 5 ) a ( * 3 a ))

Use 1 instead of :else / :default in cond :

; 24 chars ( cond ( = m p ) a ( < m p ) b :else c ) ; 20 chars ( cond ( = m p ) a ( < m p ) b 1 c )

Use maps instead of if s for conditions on equality (this one really makes the code harder to read):