# Clojure Programming/Examples/Cookbook

## BindingEdit

### How to do structural binding or destructuring in function argument lists or let bindings.Edit

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=> (list-xyz {:x 1, :y 2 :z 3})
(1 2 3)
```

You can destructure the map like this:

```(defn list-xyz [{x :x, y :y, z :z}]
(list x y z))

user=> (list-xyz {:x 1, :y 2, :z 3})
(1 2 3)
```

or better yet, like this:

```(defn list-xyz [{:keys [x, y, z]}]
(list x y z))

user=> (list-xyz {:x 1, :y 2 :z 3})
(1 2 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=> (vec-norm [1, 2, 3])
3.7416573867739413
```

## LoopingEdit

### Loop through the items in a sequenceEdit

```user=> (doseq [ item '((1 2) [3 4] "D")] (prn item))
(1 2)
[3 4]
"D"
nil

user=> (doseq [item {:a 1 :b 2}] (prn item))
[:b 2]
[:a 1]

user=> (for [item {:a 1 :b 2}] item)
([:a 1] [:b 2])
```

### for loopEdit

```user=> (dotimes [i 4] (prn i))
0
1
2
3
```

### recursive loopingEdit

```(defn my-zipmap [keys vals]
(loop [my-map {}
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)))

(println (my-zipmap [:a :b :c] [1 2 3]))

{:c 3, :b 2, :a 1}
```

## Modifying StateEdit

### How to write x = x+ 1Edit

```user=> (def x (atom 0))
#'user/x
user=> (swap! x + 1)
1
user=> (swap! x + 1)
2
user=> @x
2
```

Or, a more idiomatic way would be to use inc:

```user=> (def x (atom 0))
#'user/x
user=> (swap! x inc)
1
user=> (swap! x inc)
2
user=> @x
2
```

The most idiomatic way is not do this at all. Why would you want to do x=x+1 in clojure?

## SetsEdit

### How to create a setEdit

```(def p #{1,2,3})
```

### How to find union/intersection/difference of setsEdit

```(def a #{1,2,3,4})
(def b #{2,3,5})

user=> (clojure.set/union a b)
#{1 2 3 4 5}

user=> (clojure.set/intersection a b)
#{2 3}

user=> (clojure.set/difference a b)
#{1 4}
```

## SequencesEdit

### OperationsEdit

#### Create a list of n copies of an objectEdit

```user=> (repeat 10 "a")
("a" "a" "a" "a" "a" "a" "a" "a" "a" "a")
```

#### Create a list of n calls to a function of no argumentEdit

```; repeatedly generates an infinite sequence of calls to a function that takes no arguments
; No calls are made until the result is needed! (do not try to evaluate this list directly, it is infinite,
; and will run forever)
user=> (def random-ints (repeatedly #(rand-int 100)))

; use take to take the integers:
user=> (take 10 random-ints)
(66 8 31 90 78 18 28 8 94 3)

;NOTE: seqs are cached, so taking new random ints will always return the same result.
;This also means that if you take many ints from a global seq (def'd one) ALL the integers will
;stay in memory until the name is redefined to something else!

user=> (take 15 random-ints) ; first 10 are the same, 5 new ints generated
(66 8 31 90 78 18 28 8 94 3 84 29 71 85 41)

; to avoid a global list, you can do this:
(defn make-calls [n func]
(take n (repeatedly func)))

; no fear of keeping huge lists in memory this time (unless you hold onto them, of course)
user=> (make-calls 5 #(rand-int 100))
(60 75 89 62 36)

; upon next call, the result will be different:
user=> (make-calls 5 #(rand-int 100))
(94 95 88 11 93)
```

#### append or concatenate two more sequences togetherEdit

```user=> (concat [1 3] [3 4 3] [3 3])
(1 3 3 4 3 3 3)
```

### Infinite SequencesEdit

#### generate an infinite cyclic listEdit

```(def x (cycle [1 2 3]))

user=> (take 12 x)
(1 2 3 1 2 3 1 2 3 1 2 3)
```

#### generate an infinite sequence of random numbersEdit

```(def rands (repeatedly rand))

user=> (take 4 rands)
(0.39300911409554096 0.24329175257444235 0.03259576739916903 0.7459916914364135)
user=>
```

#### generate an infinite repeating sequenceEdit

```(def just4 (repeat 4))

user=> (take 5 just4)
(4 4 4 4 4)
```

#### generate infinite sequence of nested function callsEdit

The infinite sequence (0 1 2 3 4 5 ....) can be defined using (range) since clojure 1.2:[1]

``` (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)
```

## PolymorphismEdit

Overload function based on number of arguments:

```(defn argcount
([] 0)                                ; Zero arguments
([x] 1)                               ; One argument
([ x &  args] (inc (count args))))    ; List of arguments

(argcount)
;; ⇒ 0
(argcount "dog")
;; ⇒ 1
(argcount "cat" 1 3 4)
;; ⇒ 4
```

Create multi-method which dispatches on the number of its arguments:

```(defmulti g (fn[& arglist] (count arglist)))
(defmethod g 0 [& arglist] "No arguments.")
(defmethod g 1 [& arglist] "One argument.")
(defmethod g 2 [& arglist]  "Two arguments.")
(defmethod g :default [& arglist] "More than two 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:

```(comment Define f to be a multi-method function and dispatch using class of argument)
(defmulti f class)

(comment Use this definition for f if the class of the argument x is a long)
(defmethod f Long [x] "Argument is a long")

(comment Use this definition for f if the class of the argument x is a double)
(defmethod f Double [x] "Argument is a double")

(comment Use this definition for f for all other argument types )
(defmethod f :default [x] "Argument is not a number")

(f 3)               ; ⇒ "Argument is a long"
(f 3.4)             ; ⇒ "Argument is a double"
(f "string")        ; ⇒ "Argument is not a number"
```
```(comment Define g to be a multi-method function which dispatches on the class of its arguments)
(defmulti g (fn[x,y] [(class x) (class y )]))

(comment Use this definition for g if class of first argument is a long and class of second argument is a long)
(defmethod g [Long,Long]  [x,y] "Both arguments are longs")

(comment Use this definition for g if class of first argument is long and class of second argument is double)
(defmethod g [Long,Double] [x,y] "First argument is a long and second argument is a double")

(comment Use this definition for g as the default )
(defmethod g :default [x,y] "All other cases")

(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:

```(comment Create multi method h that dispatches on the value of the argument)
(defmulti h (fn[x] x))

(comment Use this definition for h if argument is 4)
(defmethod h 4 [x] "argument is 4")

(comment Use this definition for other values of h)
(defmethod h :default [x] "argument is not 4")

(h 4)          ; ⇒ "argument is 4"
(h 3)          ; ⇒ "argument is not 4"
(h [3 34])     ; ⇒ "argument is not 4"

(comment Create multi method h that dispatches on the value of the argument being in an interval)
(defmulti h (fn [x] (<= 4 x 10)))

(comment Use this definition for h if argument is between 4 and 10 )
(defmethod h true [x] "argument is between 4 and 10")

(comment Use this definition for other values of h)
(defmethod h :default [x] "argument is not between 4 and 10")

(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"
```

## JavaEdit

### Instantiate a new Java objectEdit

```(new JFrame)

;; or
(JFrame.)
```

### Call a static method of a java classEdit

```user=> (Math/cos 3)
-0.9899924966004454

user=> (. Math cos 3)
-0.9899924966004454
```

### Call non-static method of a java objectEdit

```;;method name first
(.getContentPane frame)

;;object first
(. frame getContentPane)
```

### Accessing inner classesEdit

Class definition in Java.

```public class OkCancelDialog {
//Inner class
public static enum State {
OK, CANCEL;
};
}
```
```;;accessing the inner class and its static fields
(println OkCancelDialog\$State/OK)
(println OkCancelDialog\$State/CANCEL)
```

### Nested series of method callsEdit

```;; equivalent to frame.getContentPane.getSize()
(.. frame getContentPane getSize)
```

### Simple Drawing in a windowEdit

```(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)
.pack
.show))

(make-frame (make-panel))
```

### Import Java Classes from Jar FileEdit

```(import '(cljext.swing DelegatingPanel IPainter))
```

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:

```(import '(org.jfugue Anticipator))
```

Not:

```(import '(jarfilename Anticipator))
```

## File IOEdit

```(use 'clojure.contrib.duck-streams)
```

### Read entire contents of file into stringEdit

```(slurp "somefile.txt")
```

### Write to Output FileEdit

Writing creates a new file or will overwrite existing file

```(spit "output.txt" "some output text")
```

To append to existing file use "spit" with ":append" set to true

```(spit "output.txt" "more text with spit append" :append true)
```

Now our file should say:

```"some output textmore text with spit append"
```

## StringsEdit

Use str to concatenate strings:

```(str "A" "B" "C")
;; ⇒ "ABC"
```

and use apply with str as an argument to concatenate a sequence of strings:

```(apply str ["A" "B" "C"])
;; ⇒ "ABC"
(apply str ["/usr/include" \/ "stdio.h"])
;; ⇒ "/usr/include/stdio.h"

(map
(fn [file] (str "/usr/include/" file ".h"))
["stdio" "gmp" "signal"])
;; ⇒ ("/usr/include/stdio.h" "/usr/include/gmp.h" "/usr/include/signal.h")
```

Use interpose to join a sequence of strings with a separator:

```(apply str (interpose \: ["A" "B" "C"]))
;; ⇒ "A:B:C"

(apply str
(interpose \:
["/usr/local/sbin" "/usr/local/bin" "/usr/sbin" "/usr/bin" "/sbin" "/bin"]))
;; ⇒ "/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 "_":

```(re-seq #"\w+" "to be or not to be")
;; ⇒ ("to" "be" "or" "not" "to" "be")
```

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:

```(reverse "I am cold")
;; ⇒ (\d \l \o \c \space \m \a \space \I)

(apply str (reverse "I am cold"))
;; ⇒ "dloc ma I"
```

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 CallsEdit

### Get the current working directoryEdit

```user=> (System/getProperty "user.dir")
"/Applications/clojure"
```

### Set the current working directory (result is prior working directory)Edit

```user=> (System/setProperty "user.dir" "~/test")
"/Applications/clojure"
```

## ReferencesEdit

1. range on ClojureDocs