-
Ratio type:
(/ 22 7)
#> 22/7 -
Use a floating-point literal for forcing the division
(/ 22.0 7)
#> 3.142857142857143 -
The integer quotient and remainder
(quot 22 7)
#> 3
(rem 22 7)
#> 1 -
Append M to a number to create a
BigDecimal
literal:(+ 1 (/ 0.00001 1000000000000000000))
#> 1.0(+ 1 (/ 0.00001M 1000000000000000000))
#> 1.00000000000000000000001M -
For arbitrary precision integers, you can append N to create a
BigInt
literal:(* 1000N 1000 1000 1000 1000 1000 1000)
#> 1000000000000000000000N -
(odd? x)
returns true if n is odd, throws an exception if n is not an integer. -
(even? x)
returns true if n is even, throws an exception if n is not an integer. -
(< x)
(< x y)
(< x y & more)
returns true if the numbers are in strictly increasing order, false otherwise. -
(<= x)
(<= x y)
(<= x y & more)
returns true if the numbers are in monotically increasing order, false otherwise. -
(> x)
(> x y)
(> x y & more)
returns true if the numbers are in strictly decreasing order, false otherwise. -
(>= x)
(>= x y)
(>= x y & more)
returns true if the numbers are in monotically decreasing order, false otherwise. -
(inc x)
returns x plus 1, does not auto-promote longs, will throw on overflow. -
(dec x)
returns x minus 1, does not auto-promote longs, will throw on overflow. -
Multiline strings
"This is a\nmultiline string"
#> "This is a\nmultiline string"
"This is also
a multiline string"
#> "This is also\na multiline string" -
Using Java interop forms:
(.toUpperCase "hello")
#> "HELLO" -
Converting to a string
(str 1 2 nil 3)
#> "123" -
Character literal syntax is
\{letter}
, whereletter
can be a letter or the name of a character:backspace
,formfeed
,newline
,return
,space
, ortab
(Character/toUpperCase \s) #> \S
-
true
is true
false
is false
nil
also evaluates to false in a Boolean context
everything else evaluates to true in a Boolean context -
true?
tests whether a value is actually true, not whether the value evaluates to true in a Boolean context. The only thing that istrue?
istrue
itself:(true? true)
#> true
(true? "foo")
#> false -
nil?
andfalse?
work the same way. Onlynil
isnil?
, and onlyfalse
isfalse?
. -
zero?
works with any numeric type, returning true if it is zero:(zero? 0.0)
#> true
(zero? (/ 22 7))
#> false -
The following predicates test the type of their argument
(string? "hello")
#> true
(keyword? :hello)
#> true
(symbol? 'hello)
#> true
-
Map
-
Empty map:
{}
#> {} -
Some examples of literals:
{:first-name "Charlie"
:last-name "McFishwich"}
#> #<core$_GT_ clojure.core$_GT_@15cfd851>{"string-key" +}
#> {"string-key" #<core$_PLUS_ clojure.core$_PLUS_@658d00be> -
Maps can be created with the
hash-map
function(hash-map :a 1 :b 2)
#> {:a 1 :b 2} -
Look-up can be done with the
get
function.
If the key is not present,nil
is returned.(get {:a 0 :b 1} :a)
#> 0(get {:a 0 :b 1} :c)
#> nil -
It is possible to give a default value to
get
which will be returned if the key is not found.(get {:a 0 :b 1} :c -1)
#> -1 -
Another way to look up a value in a map is to treat the map like a function with the key as its argument:
({:name "The Human Coffeepot"} :name)
#> "The Human Coffeepot" -
Keywords are functions. They take a map argument and look themselves up in the map. You can look up by calling the map or by calling a key:
(def inventors {:Lisp "McCarthy" :Clojure "Hickey"})
#> #'user/inventors
(inventors :Clojure)
#> "Hickey"
:Clojure inventors)
#> "Hickey" -
The
get-in
function lets you look up values in nested maps(get-in {:a 0 :b {:c "ho hum"}} [:b :c])
#> "ho hum"
-
Empty map:
-
Vector
-
Literal:
[3 2 1]
#> [3 2 1] -
Getting the n-th value can be done with the
get
function.(get [3 2 1] 0)
#> 3 -
Vectors can also be created with the
vector
function.(vector "creepy" "full" "moon")
#> ["creepy" "full" "moon"] -
Elements can be added at the end of a vector with the
conj
function.(conj [1 2 3] 4)
#> [1 2 3 4]
-
Literal:
-
List
-
Literal:
the single quote indicates that this is not a function call, but an actual list'(1 2 3 4)
#> (1 2 3 4) -
Getting the n-th value can be done with the
nth
function.(nth '(:a :b :c) 2)
#> :c -
Lists can also be created with the
list
function.(list "creepy" "full" "moon")
#> ("creepy" "full" "moon") -
Elements can be added at the beginning of a list with the
conj
function.(conj '(1 2 3) 4)
#> (4 1 2 3)
-
Literal:
-
Set
-
Literal:
#{"kurt vonnegut" 20 :icicle}
#> #{:icicle "kurt vonnegut" 20} -
Hash sets can also be created with the
hash-ser
function.(hash-set 1 1 2 2)
#> #{1 2} -
Elements can be added with the
conj
function.(conj #{:a :b} :c)
#> #{:a :b :c} -
To test if a value is in a set, use the
contains?
function.(contains? #{:a :b} :a)
#> true
(contains? #{:a :b} 3)
#> false
(contains? #{nil} nil)
#> true -
To test if a value is in a set, we can also use the
get
function. But testing onnil
will always returnnil
.(get #{:a :b} :a)
#> :a
(get #{:a nil} nil)
#> nil
(get #{:a :b} "kurt vonnegut")
#> nil -
To test if a value is in a set, we can also use a keyword.
(:a #{:a :b}) #> :a
-
Literal:
-
To define your own functions, use
defn
(defn name doc-string? attr-map? [params*] body)
attr-map
associates metadata with the function'svar
.(defn greeting
"Returns a greeting of the form 'Hello, username.'"
[username]
(str "Hello, " username))
(greeting "world")
#> "Hello, world"
(doc greeting)
-------------------------
exploring/greeting
([username])
Returns a greeting of the form 'Hello, username.' -
You can use this alternate form of
defn
, which takes multiple argument lists and method bodies(defn name doc-string? attr-map?
([params*] body)+)greeting
that delegates to the one-argumentgreeting
, passing in a defaultusername
(defn greeting
"Returns a greeting of the form 'Hello, username.'
Default username is 'world'."
([] (greeting "world"))
([username] (str "Hello, " username)))
(greeting)
#> "Hello, world" -
You can create a function with variable arity by including an ampersand in the parameter list. Clojure will bind the name after the ampersand to a sequence of all the remaining parameters.
(defn date [person-1 person-2 & chaperones]
(println person-1 "and" person-2
"went out with" (count chaperones) "chaperones."))
(date "Romeo" "Juliet" "Friar Lawrence" "Nurse")
#> Romeo and Juliet went out with 2 chaperones. -
fn
defines an anonymous function.(fn [x] (* x x))
((fn [x] (* x x)) 10)
-
defn
is just syntaxic sugar arounddef
andfn
(def square (fn [x] (* x x)))
-
#(…)
is shorthand for(fn [arg1 arg2 …] (…))
(where the number ofargN
depends on how many%N
you have in the body). -
(#(+ %1 %2 %3) 2 4 6)
((fn [a b c] (+ a b c)) 2 4 6)
-
to use it for writing
((fn [x] [1 2 x]) 6)
:
(#([1 2 %]) 6)
becomes((fn [arg] ([1 2 arg])) 6)
and will not work.
(#(identity [1 2 %]) 6)
or(#(-> [1 2 %]) 6)
will do the trick. -
A higher order function is a function that takes another function as an argument.
map
is a higher order function. -
memoize
returns a memoized version of a function(memoize f)
-
trampoline
can be used to convert algorithms requiring mutual recursion without stack consumption. Callsf
with supplied arguments, if any. Iff
returns a fonction, calls that function with no arguments, and continues to repeat, until the return value is not a functionn, then returns that non-function value. Note that if you want to return a function as a final value, you must wrap it in some data structure and unpack it aftertrampoline
returns.(trampoline f)
(trampoline f & args)
-
When you require a library named
foo.bar.quux
, Clojure looks for a file namedfoo/bar/quux.clj
on theCLASSPATH
.(require 'foo.bar.quux)
#> nil
(take 10 foo.bar.quux/fibs)
#> (0 1 1 2 3 5 8 13 21 34) -
Fully qualified names get old quickly. You can refer a namespace, creating mappings for all its names in your current namespace
(require 'foo.bar.quux)
#> nil
(refer 'foo.bar.quux)
#> nil
(take 10 fibs)
#> (0 1 1 2 3 5 8 13 21 34) -
use
performsrequire
andrefer
in a single step(use 'foo.bar.quux)
#> nil
(take 10 fibs)
#> (0 1 1 2 3 5 8 13 21 34) -
:reload
flag forces a library to reload(use :reload 'foo.bar.quux)
(not x)
returns true
if x is logical false, false
otherwise.
(or)
(or x)
(or x & next)
evaluates expressions one at a time, from left to right. If a form returns a logical true value, or
returns that value and doesn't
evaluate any of the other expressions, otherwise it returns the value of the last expression. (or)
returns nil
.
(and)
(and x)
(and x & next)
evaluates expressions one at a time, from left to right. If a form returns logical false (nil
or false
), and
returns that value and doesn't evaluate any of the other expressions, otherwise it returns the value of the last expression. (and)
returns true
.
(= x)
(= x y)
(= x y & more)
returns true if x equals y, false if not.
(not= x)
(not= x y)
(not= x y & more)
returns the same as (not (= obj1 obj2))
.
(first coll)
returns the first item in the collection. Calls seq
on its argument. If coll is nil
, returns nil
.
(rest coll)
returns a possibly empty seq of the items after the first. Calls seq
on its argument.
(cons x seq)
returns a new seq where x is the first element and seq is the rest.