(operator operand1 operand2 ... operandn)
(str "you say goodbye" "...and I say hello!")
(+ 1 2)
(map inc [1 2 3 4])
(if condition
(statement for true)
(statement for false) ;; can be ommited, in which case returns nil if falsey
(when true
(first line of the block
second line
.
.
.
n lines for the blocks))
{:name "Rodrigo :age 21} ;; create a hash-map literal
(hash-map :name "Rodrigo" :age 21) ;; create a hash-map through the hash-map function
(get {:a 1 :b 2} :b) ;; => 2
(get {:a 1 :b {:c 2 :d 3}} :b) ;; => {:c 2 :d 3}
(get (get {:a 1 :b {:c 2 :d 3}} :b) :c) ;; => 2
(get-in {:a 1 :b {:c 2 :d 3}} [:b :c]) ;; => 2
(get {:a 1} :c) ;; => nil (for non-existent key)
(get {:a 1} :c "unicorns?") ;; => "unicorns?" (default value)
[1 2 3] ;; => [1 2 3] creates a vector literal
(vector 1 2 3) ;; [1 2 3] creates a vector through the vector function
(vector [1 {a: "opa" b: 1/2} "da string" 23/39]) ;; => [1 {a: "opa" b: 1/2} "da string" 23/39] a vector accepts any type
(get [25 35 300] 0) ;; => 1 (0th element)
(get [25 35 300] 2) ;; => 300 (2nd element)
(get [25 35 300] 3) ;; => nil (there's no 3rd element)
([25 35 300] 0) ;; => 1 (0th element)
([25 35 300] 3) ;; => throws IndexOutOfBoundsException (different behaviour from `(get [25 35 300] 3)`)
(conj [1 2 3] 4 5 6) ;; => [1 2 3 4 5 6] (elements are added at the end of the vector)
'(1 2 3 4) ;; => (1 2 3 4) creates a list literal
(list 1 :simbolo {:name "Cartman" :age 7} 1/2) ;; => (1 :simbolo {:name "Cartman" :age 7} 1/2) creates a list
(nth '(1 2 3 4) 0) ;; => 1
(nth '(1 2 3 4) 4) ;; => throws IndexOutOfBoundException
(conj '(1 2 3) 4 5 6) ;; => (6 5 4 1 2 3) (elements are added at the beginning of the list)
For a nubie (as I am), the rule of thumb is:
use a
list
when you need to addelements
at the beginning of asequence
. Or when you write amacro
. Otherwise, usevector
. - Daniel Higginbotham (Clojure for the Brave and True)
Sets are collections of unique elements.
#{"awesome" 1 :simbolo 1/4} => #{"awesome" 1 :simbolo 1/4} creates a hash-set literal
(hash-set "awesome 1 :simbolo 1/4) => #{"awesome" 1 :simbolo 1/4} creates a hash-set
(hash-set 1 1 2 2) => #{1 2}
(hash-set [1 1 2 2]) => #{[1 1 2 2]}
(hash-set [1 1 2 2] [1 1 2 2]) => #{[1 1 2 2]}
#{1 1 2 2} => throws IllegalArgumentException (Duplicate key)
(set [1 1 2 2]) => #{1 2} creates a set with the given vector
(contains? #{1 2} 1) => true
(contains? #{nil "a"} nil) => true
(:a #{:a :2}) => :a finds the element using the keyword as the function and the set as the argument for that function
(nil #{:a :2}) => throws IllegalArgumentException - Can't call nil
("word" #{"word" 1}) => throws ClassCastException - String cannot be cast to clojure.lang.IFn
(1 #{"word" 1}) => throws ClassCastException - java.lang.Long cannot be cast to clojure.lang.IFn
(get #{1 "a"} "a") => "a"
(get #{1 1/4} 1/4) => 1/4
(get #{nil 123} nil) => nil
(get #{1 2 3} 85) = nil
Notice that using get to test whether a set contains nil will always return nil, which is confusing. - Daniel Higginbotham (Clojure for the Brave and True)
Binds values to new symbols. Values can be expressions. It's a way of saying: "create local names for existent values"
(def musics ["Phosphene Dream" "Pink Cigarrete" "Beyond the Realms of Death"])
(let [couple (take 2 musics)]
(print couple)) => (Phosphene Dream Pink Cigarrete)
(def musics ["Phosphene Dream" "Pink Cigarrete" "Beyond the Realms of Death"])
(let [[first-music & the-list] musics]
[first-music the-list]) => ["Phosphene Dream" ("Pink Cigarrete" "Beyond the Realms of Death")]
(loop [iteration 0]
(println "Iteration " iteration)
(if (> iteration 9)
(println "Got it, exiting")
(recur (inc iteration))))
; => Iteration 0
; => Iteration 1
; => Iteration 2
; => Iteration 3
; => Iteration 4
; => Iteration 5
; => Iteration 6
; => Iteration 7
; => Iteration 8
; => Iteration 9
; => Got it, exiting