Clojure Programming/Examples/Cookbook

Binding.
How to do structural binding or destructuring in function argument lists or let bindings..
Instead of accessing values in a map like this:
(defn list-xyz [xyz-map]
 (list (:x xyz-map) (:y xyz-map) (:z xyz-map)))
user=&gt; (list-xyz {:x 1, :y 2 :z 3})
You can destructure the map like this:
(defn list-xyz [{x :x, y :y, z :z}]
 (list x y z))
user=&gt; (list-xyz {:x 1, :y 2, :z 3})
or better yet, like this:
(defn list-xyz [{:keys [x, y, z]}]
 (list x y z))
user=&gt; (list-xyz {:x 1, :y 2 :z 3})
Instead of accessing vector elements like this:
(defn vec-norm [vec3]
 (Math/sqrt (+ (* (nth vec3 0) (nth vec3 0))
 (* (nth vec3 1) (nth vec3 1))
 (* (nth vec3 2) (nth vec3 2)))))
you can destructure the vector like this:
(defn vec-norm x, y, z
 (Math/sqrt (+ (* x x) (* y y) (* z z))))
user=&gt; (vec-norm [1, 2, 3])
3.7416573867739413
Looping.
Loop through the items in a sequence.
user=&gt; (doseq [ item '((1 2) [3 4] "D")] (prn item))
[3 4]
"D"
nil
user=&gt; (doseq [item {:a 1 :b 2}] (prn item))
[:b 2]
[:a 1]
user=&gt; (for [item {:a 1 :b 2}] item)
for loop.
user=&gt; (dotimes [i 4] (prn i))
0
1
2
3
recursive looping.
(defn my-zipmap [keys vals]
 my-keys keys
 my-vals vals]
 (if (and (seq my-keys) (seq my-vals))
 (recur (assoc my-map (first my-keys) (first my-vals))
 (rest my-keys)
 (rest my-vals))
 my-map)))
Modifying State.
How to write x = x+ 1.
user=&gt; (def x (atom 0))
user=&gt; (swap! x + 1)
1
user=&gt; (swap! x + 1)
2
user=&gt; @x
2
Or, a more idiomatic way would be to use inc:
user=&gt; (def x (atom 0))
user=&gt; (swap! x inc)
1
user=&gt; (swap! x inc)
2
user=&gt; @x
2
The most idiomatic way is not do this at all. Why would you want to do x=x+1 in clojure?
Sets.
How to find union/intersection/difference of sets.
user=&gt; (clojure.set/union a b)
user=&gt; (clojure.set/intersection a b)
user=&gt; (clojure.set/difference a b)
Sequences.
Operations.
Create a list of n copies of an object.
user=&gt; (repeat 10 "a")
Create a list of n calls to a function of no argument.
user=&gt; (def random-ints (repeatedly #(rand-int 100)))
user=&gt; (take 10 random-ints)
user=&gt; (take 15 random-ints) ; first 10 are the same, 5 new ints generated
(defn make-calls [n func]
 (take n (repeatedly func)))
user=&gt; (make-calls 5 #(rand-int 100))
user=&gt; (make-calls 5 #(rand-int 100))
append or concatenate two more sequences together.
user=&gt; (concat [1 3] [3 4 3] [3 3])
Infinite Sequences.
generate an infinite cyclic list.
user=&gt; (take 12 x)
generate an infinite sequence of random numbers.
user=&gt; (take 4 rands)
user=&gt;
generate an infinite repeating sequence.
user=&gt; (take 5 just4)
generate infinite sequence of nested function calls.
The infinite sequence (0 1 2 3 4 5 ...) can be defined using (range) since clojure 1.2:
 (def integers (range))
 (take 10 integers)
 ;; ⇒ (0 1 2 3 4 5 6 7 8 9)
or alternatively using iterate:
 ;; Generates (x (inc x) (inc (inc x)) ...)
 (def integers (iterate inc 0))
 (take 4 integers)
 ;; ⇒ (0 1 2 3)
 (def newton (iterate (fn[x] (/ (+ x (/ 2.0 x)) 2)) 2))
 (take 5 newton)
 ;; ⇒ (2 1.5 1.4166666666666665 1.4142156862745097 1.4142135623746899)
Polymorphism.
Overload function based on number of arguments:
(defn argcount
 ([] 0) ; Zero arguments
 ([x] 1) ; One argument
 ([x &amp; args] (+ 1 (count args)))) ; List of arguments
Create multi-method which dispatches on the number of its arguments:
(g) ; ⇒ "No arguments."
(g 1) ; ⇒ "One argument."
(g 2) ; ⇒ "One argument."
(g 3 4) ; ⇒ "Two arguments."
(g "cart" 1 [2 3 ]) ; ⇒ "More than two arguments."
Create a multi-method which dispatches on the class of its arguments:
(f 3) ; ⇒ "Argument is a long"
(f 3.4) ; ⇒ "Argument is a double"
(f "string") ; ⇒ "Argument is not a number"
(g 3 2) ; ⇒ "Both arguments are longs"
(g 3 4.3) ; ⇒ "First argument is a long and second argument is a double"
(g 4.3 4.3) ; ⇒ "All other cases"
Create a multi-method that dispatches on the value of its argument:
(h 4) ; ⇒ "argument is 4"
(h 3) ; ⇒ "argument is not 4"
(h [3 34]) ; ⇒ "argument is not 4"
(h 1) ; ⇒ "argument is not between 4 and 10"
(h 4) ; ⇒ "argument is between 4 and 10"
(h 10) ; ⇒ "argument is between 4 and 10"
(h 11) ; ⇒ "argument is not between 4 and 10"
Java.
Call a static method of a java class.
user=&gt; (Math/cos 3)
-0.9899924966004454
user=&gt; (. Math cos 3)
-0.9899924966004454
Accessing inner classes.
Class definition in Java.
public class OkCancelDialog {
 //Inner class
 public static enum State {
 OK, CANCEL;
Simple Drawing in a window.
(ns drawing-demo
 (:import [javax.swing JPanel JFrame]
 [java.awt Dimension]))
(defn make-panel []
 (let [panel (proxy [JPanel] []
 (paintComponent [g]
 (.drawLine g 0 0 100 100)))]
 (doto panel
 (.setPreferredSize (Dimension. 400 400)))))
(defn make-frame [panel]
 (doto (new JFrame)
 (.add panel)
 .pack
 .show))
Import Java Classes from Jar File.
The first item in the import list is the package name followed by the names of all the classes in the package to import.
Note: you must use the package name and not the name of the jar file which contains the package of classes.
If you're not sure what the package name is, from a terminal type:
jar tf jarfilename.jar
Let's say you see something like: org/jfugue/Anticipator.class
Then the import statement would be:
Not:
File IO.
Write to Output File.
Writing creates a new file or will overwrite existing file
To append to existing file use "spit" with ":append" set to true
Now our file should say:
"some output textmore text with spit append"
Strings.
Use str to concatenate strings:
and use apply with str as an argument to concatenate a sequence of strings:
(map 
 (fn [file] (str "/usr/include/" file ".h"))
 ["stdio" "gmp" "signal"])
Use interpose to join a sequence of strings with a separator:
(apply str 
 (interpose \:
 ["/usr/local/sbin" "/usr/local/bin" "/usr/sbin" "/usr/bin" "/sbin" "/bin"]))
Use re-seq to split a string at boundaries by a regular expression, here \w+ denotes a character class of all alphanumeric characters plus "_":
Reversing a string is done via reverse which returns a sequence of the characters in the string; use apply with str to turn it into a string again:
and to convert any object into a string simply supply it as an argument to the str function:
(str 3) ; ⇒ "3"
(str 3.0) ; ⇒ "3.0"
(str 'a) ; ⇒ "a"
(str '(1 2)) ; ⇒ "(1 2)"
(str {:a 1 :b 2}) ; ⇒ "{:a 1, :b 2}"
Operating System Calls.
Get the current working directory.
user=&gt; (System/getProperty "user.dir") 
"/Applications/clojure"
Set the current working directory (result is prior working directory).
user=&gt; (System/setProperty "user.dir" "~/test") 
"/Applications/clojure"