Paweł Kapała
http://imgs.xkcd.com/comics/compiling.png
Read
Eval
Loop
All while the app is running!
0.2
2/3
2
5302542730
"Wawel"
"Kraków"
"hello world"
"John"
"Mścigniew"
:title
:id
:chupacabra
:name
("a" "b" "c" "d" "e" "f")
(0 1 2 3 4 5 6 7)
(:a :b :c :d :e)
()
[0 1 2 3 4 5 6]
["John" "Jane" "Lucy"]
[:title :name :id]
{:id 1 :name "John" :surname "Doe"}
{:subject "this" :predicate "is"
:preposition "a" :object "map"}
a-symbol
bar
namespace/example
iamfoo
(str "a" "b" "c")
(conj [] 1 2 3 4)
(+ 2 4 6 7)
(first [1 2 3 4])
(assoc {:id 1 :name "John"} :surname "Doe")
(= {:id 1 :name "Joe"} {:id 1 :name "Joe"})
(defn greeter [arg1 arg2]
(str "Hello " arg1 " " arg2 "!"))
(defn plus [arg1 arg2]
(+ arg1 arg2))
#(+ %1 %2)
#(str "Hello " %1 " " %2 "!")
*at least for the most part
{:name "Krakus" :health 100}
(defn citizen [name]
{:name name :health 100})
(citizen "Krakus")
{:name "Krakus" :health 100 :title :king}
(defn promote [citizen title]
(assoc citizen :title title))
(defn king [name]
(promote (citizen name) :king))
(king "Krakus")
assoc returns new map with key value added to it
{:name "Wawel"}
(defn castle [name]
{:name name})
(castle "Wawel")
{:name "Wawel" :citizens [
{:name "Krakus" :health 100 :title :king}]}
(defn occupy [what whom]
(update what :citizens
(fnil conj []) whom))
(occupy (castle "Wawel") (king "Krakus"))
update returns map with a specified key changed by given function
conj returns collection with element appended
fnil executes specified function passing argument in case of nil
{:energy 10 :size 10}
(defn food [energy]
{:energy energy :size 10})
(defn ram[] (food 10))
(defn cow[] (food 20))
(ram)
{:name "Wawel" :goods [{:energy 10 :size 10}]}
(defn store [structure food]
(update structure :goods
(fnil conj []) food))
(store (castle "Wawel") (ram))
({:energy 20 :size 10}
{:energy 20 :size 10}
{:energy 20 :size 10}
;... 15 more
{:energy 20 :size 10}
{:energy 20 :size 10})
(repeatedly 20 cow)
repeatadly returns (lazy) collection containing function result times the number specified, or infinite if size is not specified
(defn knight [name]
(assoc
(promote (citizen name) :knight)
:power 100))
(knight "Małowuj")
{:name "Małowuj" :title :knight :power 100}
{:name "Wawel" :citizens [
{:name "Małowuj" :title :knight :power 100 :health 100}
{:name "Minigniew" :title :knight :power 100 :health 100}
{:name "Gromisław" :title :knight :power 100 :health 100}
{:name "Nowosiodł" :title :knight :power 100 :health 100}
{:name "Twardomir" :title :knight :power 100 :health 100}
{:name "Włościobyt" :title :knight :power 100 :health 100}]}
(reduce occupy (castle "Wawel")
(map knight ["Małowuj" "Minigniew" "Gromisław"
"Nowosiodł" "Twardomir" "Włościobyt"]))
map executes function for each collection element and returns a collection of results
reduce calls two-arg function on a first element of the collection, then passes the return back to the function as a first argument and takes next element of the collection...
(defn dragon [name]
{:name name :health 1000 :power 1000})
(dargon "Smok")
{:name "Smok" :health 1000 :power 1000}
(occupy (castle "Wawel") (dragon "Smok"))
{:name "Wawel" :citizens [{:name "Smok"
:health 1000 :power 1000}]
(defn eat [who what]
(merge-with + who what))
(eat (dragon "Smok") (ram))
{:name "Smok" :health 1000 :power 1000
:energy 10 :size 10}
merge-with combines two map into one using provided function (+ in this case) on the values of matching keys
(defn attack [target who]
(update target :health
(fnil - 0) (:power who 0)))
(attack (dragon "Smok") (knight "Minigniew"))
{:name "Smok" :health 900 :power 1000}
; {:name "Minigniew" :health -900
; :title :knight :power 100}
true
(defn dead? [who]
(<= (:health who 0) 0))
(dead?
(attack (knight "Minigniew") (dragon "Smok")))
(defn sulfur []
{:thirst 500})
(defn tar []
{:size 500))
(defn ram-with-sulfur-and-tar []
(merge-with + (ram) (sulfur) (tar)))
(ram-with-sulfur-and-tar)
{:energy 10 :size 510 :thirst 500}
(eat (dragon "Smok")
(ram-with-sulfur-and-tar))
{:name "Smok" :health 1000 :power 1000
:energy 10 :size 510 :thirst 500}
(defn water []
{:thirst -1 :size 10})
(defn vistula []
(repeatedly water))
(take 100 (vistula))
({:thirst -1 :size 10}
{:thirst -1 :size 10}
{:thirst -1 :size 10}
{:thirst -1 :size 10}
;... 96x more
)
({:name "Smok-0" :health -1000 :power 1000}
{:name "Smok-1" :health -1000 :power 1000}
{:name "Smok-2" :health -1000 :power 1000}
{:name "Smok-3" :health -1000 :power 1000}
;... 96x more
)
(defn pieceof [who no]
(-> who
(update :name str "-" no)
(assoc :health -1000)))
(map #(pieceof (dragon "Smok") %1) (range 100))
-> Is called "a threading macro" that passes result of previous function call as first parameter to next call in block, the above is equivalent to:
(assoc (update who :name str "-" no) :health -1000)
https://github.com/kapware/clj-krakus/
4clojure.com
Clojure for the Brave and True
clojure.org
Structure and interpretation of computer programs
Mastering Clojure
clojurekoans.com
(code)