Binding [ edit ]

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

Looping [ edit ]

Loop through the items in a sequence [ edit ]

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 loop [ edit ]

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

recursive looping [ edit ]

( 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 State [ edit ]

How to write x = x+ 1 [ edit ]

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?

Sets [ edit ]

How to create a set [ edit ]

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

How to find union/intersection/difference of sets [ edit ]

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

Sequences [ edit ]

Operations [ edit ]

Create a list of n copies of an object [ edit ]

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 argument [ edit ]

; 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 together [ edit ]

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

Infinite Sequences [ edit ]

generate an infinite cyclic list [ edit ]

( 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 numbers [ edit ]

( def rands ( repeatedly rand )) user=> ( take 4 rands ) ( 0.39300911409554096 0.24329175257444235 0.03259576739916903 0.7459916914364135 ) user=>

generate an infinite repeating sequence [ edit ]

( def just4 ( repeat 4 )) user=> ( take 5 just4 ) ( 4 4 4 4 4 )

generate infinite sequence of nested function calls [ edit ]

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)

Polymorphism [ edit ]

Overload function based on number of arguments:

( defn argcount ( [] 0 ) ; Zero arguments ( [x] 1 ) ; One argument ( [x & args] ( + 1 ( 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"

Java [ edit ]

Instantiate a new Java object [ edit ]

( new JFrame ) ;; or ( JFrame. )

Call a static method of a java class [ edit ]

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

Call non-static method of a java object [ edit ]

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

Accessing inner classes [ edit ]

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 calls [ edit ]

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

Simple Drawing in a window [ edit ]

( 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 )) ( make-frame ( make-panel ))

Import Java Classes from Jar File [ edit ]

( 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 IO [ edit ]

Load File IO library [ edit ]

( use 'clojure.contrib.duck-streams )

Read entire contents of file into string [ edit ]

( slurp "somefile.txt" )

Write to Output File [ edit ]

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"

Strings [ edit ]

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 Calls [ edit ]

Get the current working directory [ edit ]

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"