16
\$\begingroup\$

What are your tips for code golfing using Clojure?

The aim of this question is to collect a list of techniques that are specific to Clojure and can be used in general code-golfing problems.

\$\endgroup\$
1
  • \$\begingroup\$ Hmm.. shouldn't these types of posts be in meta (granted I'm not sure meta existed 5+ years ago) \$\endgroup\$ – Albert Renshaw Mar 30 '17 at 0:14

10 Answers 10

6
\$\begingroup\$

Use reader syntax for lambdas.
So use

#(+ % %2 %3)

instead of

(fn [x y z] (+ x y z))

You can also eliminate whitespace some of the time:

#(if (< % 0) (- %) %)
#(if(< % 0)(- %)%)
\$\endgroup\$
1
  • \$\begingroup\$ by the way #(+ % %2 %3) is equivalent to +. \$\endgroup\$ – bfontaine Nov 30 '19 at 12:37
4
\$\begingroup\$

Where you can remove whitespace:

  • Between a string and anything else:

    (println(+"Hello, World!"1))
    
  • Between brackets and anything else:

    (for[x(range 5)](* x x))
    
  • Between a number and everything other than builtins or variable names:

    Allowed:
    (+ 1"Example")
    (map{1"-1"2"-2"}[1 2 3])
    
    Not allowed:
    (+1 2)
    
  • Between @ (dereference for atoms) and brackets.

\$\endgroup\$
3
  • \$\begingroup\$ Also before the deref reader macro @ \$\endgroup\$ – ASCII-only Mar 29 '17 at 22:19
  • 1
    \$\begingroup\$ Also at times you might be able to re-arrange stuff at a let and get rid of some spaces. \$\endgroup\$ – NikoNyrh Dec 14 '17 at 21:56
  • \$\begingroup\$ Also before parameters in anonymous functions: #(+ 1(first%)) = #(+ 1 (first %)) \$\endgroup\$ – bfontaine Nov 15 '19 at 20:27
3
\$\begingroup\$

Strings can be treated as a sequence of chars

e.g. to sort the characters in a string alphabetically:

(sort "hello")
=> (\e \h \l \l \o)
\$\endgroup\$
2
  • 1
    \$\begingroup\$ Strings are by definition a sequence of chars in almost every language, but you can't apply this trick in all of them :-) \$\endgroup\$ – mellamokb Jun 12 '11 at 21:44
  • 3
    \$\begingroup\$ Or rather, "sequence" has a special meaning in Clojure than means you can apply extra tricks ::-) \$\endgroup\$ – mikera Jun 13 '11 at 11:24
2
\$\begingroup\$

Use nth ... 0 instead of first

To get the first element of a collection, using (nth ... 0) over first saves a byte:

(first[2 3 4]): 14 bytes
(nth[2 3 4]0): 13 bytes (saves a byte!)
\$\endgroup\$
2
  • \$\begingroup\$ same goes for second (2 bytes) \$\endgroup\$ – Uriel Dec 14 '17 at 22:12
  • 1
    \$\begingroup\$ Also you can use vectors as functions, so ([2 3 4]1) returns the element at index 1. This should be benefitical if for example the input format is flexible. \$\endgroup\$ – NikoNyrh Dec 15 '17 at 20:30
1
\$\begingroup\$

Use apply instead of reduce

For example #(apply + %) is one byte shorter than #(reduce + %).

\$\endgroup\$
1
\$\begingroup\$

Avoid let if you already have a for

For example: #(for[a[(sort %)]...) instead of #(let[a(sort %)](for ...)).

For does also have a :let construct but it is too verbose for code golf.

\$\endgroup\$
1
\$\begingroup\$

Use + and - instead of inc and dec

This saves 1 byte if you're using inc/dec on an expression with parens:

(inc(first[1 3 5]))
(+(first[1 3 5])1)
\$\endgroup\$
1
\$\begingroup\$

Use maps instead of ifs when testing for equality

;; if n=3 then A else B
(if (= 3 n) A B) ; (if(=3n)AB)
({3 A} n B)      ; ({3A}nB) -> -3 chars

;; if n=2 or n=3 then A else B
(if (#{2 3} n) A B) ; (if(#{23}n)AB)
({2 A 3 A} n B)     ; ({2A3A}nB) -> -4 chars
\$\endgroup\$
1
\$\begingroup\$

Bind long function names at let to a single-byte symbol

For example if you need to use partition or frequencies multiple times, it could be beneficial to bind them to a single-byte symbol in a let macro. Then again it might not be worth it if you don't need the let otherwise, and the function name is relatively short.

\$\endgroup\$
0
\$\begingroup\$

Use for instead of map

For instance #(for[i %](Math/abs i)) is a lot shorter than the map equvalent.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.