stefan kanev: clojure, clojurescript and why they're awesome at i t.a.k.e. unconference 2015
Post on 12-Aug-2015
86 Views
Preview:
TRANSCRIPT
http://xkcd.com/{224,297}
Clojure & ClojureScript
Stefan Kanevhttp://skanev.com/@skanev
I.T.A.K.E. Unconf26 May 2015
Sofia
twitter: @skanev github: skanev blog: http://skanev.com/
Clojure from 10,000 feet
A modern LISP, hosted in the JVM, with a focus on concurrency
A modern LISP, hosted in the JVM, with a focus on concurrency
LISP: “that language with the parentheses”
also: a subculture
“LISP is too hip, even for me”
– a hipster
LISP
a * b + c * d
(+ (* a b) (* c d))
homoiconicitydata is code, code is
data
A modern LISP, hosted in the JVM, with a focus on concurrency
Sans the antiquities:car cdr lambda
Way better design
Less parentheses
A modern LISP, hosted in the JVM, with a focus on concurrency
Stable platform
Access to full Java ecosystem
Occasionally a huge P.I.T.A.
A modern LISP, hosted in the JVM, with a focus on concurrency
parallelism vs. concurrency
parallelism
Breaking a problem down to smaller parts that can be computed at the same time
concurrency
Synchronising a number of independent processes that are fighting for the same resources
Syntax
(func arg-1 arg-2 …)
(println "Hello world")
(+ 1 2)(< x y)
(+ 1 2 3 4 5 6)(< u v w x y z)
(+ (* a b) (* c d))
(+ (* a b) (* c d))
(defn say-hello [who] (println "Hello" who "!"))
(say-hello "Doctor")
OMG Parentheses!Or should I say:
((o) ((m)) (g) ( (( (( (( )) )) )) ))
Parentheses in LISP are not unlike metric time
(defn classify [age] (if (<= 13 age 19) "Teenager" "A normal person"))
(classify 18) ; "Teenager"
(defn factorial [n] (if (= n 1) 1 (* n (factorial (- n 1)))))
(defn fib [n] (cond (= n 0) 1 (= n 1) 1 :else (+ (fib (- n 1)) (fib (- n 2)))))
(fn [x] (* x 2))
(map (fn [n] (str "Mr. " n)) ["Anderson" "Bond" "Bean"])
; ("Mr. Anderson”; "Mr. Bond" ; "Mr. Bean")
(filter prime? (range 2 100))
; (2 3 5 7 11 13 17 19 23 29 31 37 41; 43 47 53 59 61 67 71 73 79 83 89 97)
(defn prime? [n] (not-any? (fn [x] (zero? (rem n x))) (range 2 (inc (Math/sqrt n)))))
Data Structures
maps (hashes)vectors (arrays)
sets
immutable
“Modifying” a structure creates a copy containing the change.
The original remains unmodified.
Y
simplicity
multicore ❤ immutable
persistent
The “originals” are maximally reused
a ! (3 2 1)
123
a
a ! (3 2 1)
a ! (3 2 1)b ! (conj a 4) (4 3 2 1)
123
a
a ! (3 2 1)b ! (4 3 2 1)
4b
5cc ! (conj a 5)
Hash Table
1020394597
1020205863
{:foo first, :bar second}
first
second
Hash Table
1020394597
1020205863
Hash Table
1020394597
1020205863
1021027443
(conj table :qux 1024)
not that simple
Vectors(“arrays” in other langs)
Vectors are represented by treesEach node has 32 children
log32…
…
…
… ⨯
O(?)
log32n
325 = 33 554 432
326 = 1 073 741 824
“essentially constant time”
Software Transactional Memory
concurrency 101
100 € +50 € ⨯2
How much money will the account have?
300 €250 €
100 €
+50 € = 150 €
x2 = 300 €
100 €
x2 = 200 €
+50 € = 250 €
100 €
200 €
150 €x2+50
100 €100 €
100 €
150 €
200 €
x2+50
100 €100 €
ref
state mutation is modelled as a transaction
if two transactions “get in each others’
way”, one of them will restart
(def account (ref 100))
; Thread 1 - Uncle Scrooge(dosync (alter account (fn [n] (* n 2))) (println "Scrooge: set to " @account))
; Thread 2 - Donald Duck(dosync (alter account (fn [n] (+ n 50))) (println "Donald: set to " @account))
100 €
300 €
150 €x2 +50100 €
100 €
X
x2150 €
Y
familiar
safe, easy, no deadlocks
Macros
Powerful instrument allowing expressive code
Also known as:the mother of all metaprogramming
MacroCodeSome other
code
doStuff();
Outputs on STDOUT. We want to have the result in a string instead.
PrintStream original = System.out;ByteArrayOutputStream output = new ByteArrayOutputStream();
try { PrintStream fileStream = new PrintStream(output); orgStream = System.out; System.setOut(fileStream);
doStuff();
} finally { System.setOut(original);}
String output = output.toString();
(do-stuff)
(with-out-str (do-stuff))
(with-out-str (do-stuff))
String output = withOutStr { doStuff();}
unless
(unless (hungry?) (sleep) (eat))
(if (not (hungry?)) (sleep) (eat))
(defmacro unless [condition consequent alternative] `(if (not ~condition) ~consequent ~alternative))
unless (isHungry()) { sleep();} else { eat();}
(cond (= n 0) 1 (= n 1) 1 :else (+ (fib (- n 2)) (fib (- n 1))))
(if (= n 0) 1 (if (= n 1) 1 (+ (fib (- n 2)) (fib (- n 1)))))
DSLDomain Specific Languages
Transparency
(source if-let)(source await)
ClojureScript
om
Very dynamic
DEMO
REPL Oriented Programming
top related