Skip to content

Instantly share code, notes, and snippets.

@cairesr
Last active August 29, 2016 00:31
Show Gist options
  • Save cairesr/565ae17ae98bc06f1a3b314cb7ea96fa to your computer and use it in GitHub Desktop.
Save cairesr/565ae17ae98bc06f1a3b314cb7ea96fa to your computer and use it in GitHub Desktop.
Clojure: structures

Clojure structure is always the same

(operator operand1 operand2 ... operandn)
(str "you say goodbye" "...and I say hello!")
(+ 1 2)
(map inc [1 2 3 4])

if statement

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

hash-maps

{: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)

vector

[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)

lists

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

vectors x lists

For a nubie (as I am), the rule of thumb is:

use a list when you need to add elements at the beginning of a sequence. Or when you write a macro. Otherwise, use vector. - Daniel Higginbotham (Clojure for the Brave and True)

set

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)

Let

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

(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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment