109
http://xkcd.com/{224,297}

Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

Embed Size (px)

Citation preview

Page 1: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

http://xkcd.com/{224,297}

Page 2: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

Clojure & ClojureScript

Stefan Kanevhttp://skanev.com/@skanev

I.T.A.K.E. Unconf26 May 2015

Sofia

Page 3: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015
Page 4: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

twitter: @skanev github: skanev blog: http://skanev.com/

Page 5: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

Clojure from 10,000 feet

Page 6: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

A modern LISP, hosted in the JVM, with a focus on concurrency

Page 7: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

A modern LISP, hosted in the JVM, with a focus on concurrency

Page 8: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

LISP: “that language with the parentheses”

also: a subculture

Page 9: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

“LISP is too hip, even for me”

– a hipster

Page 10: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

LISP

Page 11: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015
Page 12: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

a * b + c * d

(+ (* a b) (* c d))

Page 13: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

homoiconicitydata is code, code is

data

Page 14: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015
Page 15: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

A modern LISP, hosted in the JVM, with a focus on concurrency

Page 16: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

Sans the antiquities:car cdr lambda

Page 17: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

Way better design

Page 18: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

Less parentheses

Page 19: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

A modern LISP, hosted in the JVM, with a focus on concurrency

Page 20: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

Stable platform

Page 21: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

Access to full Java ecosystem

Page 22: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

Occasionally a huge P.I.T.A.

Page 23: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

A modern LISP, hosted in the JVM, with a focus on concurrency

Page 24: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

parallelism vs. concurrency

Page 25: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

parallelism

Breaking a problem down to smaller parts that can be computed at the same time

Page 26: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

concurrency

Synchronising a number of independent processes that are fighting for the same resources

Page 27: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

Syntax

Page 28: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

(func arg-1 arg-2 …)

Page 29: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

(println "Hello world")

Page 30: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

(+ 1 2)(< x y)

Page 31: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

(+ 1 2 3 4 5 6)(< u v w x y z)

Page 32: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

(+ (* a b) (* c d))

(+ (* a b) (* c d))

Page 33: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

(defn say-hello [who] (println "Hello" who "!"))

(say-hello "Doctor")

Page 34: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

OMG Parentheses!Or should I say:

((o) ((m)) (g) ( (( (( (( )) )) )) ))

Page 35: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

Parentheses in LISP are not unlike metric time

Page 36: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

(defn classify [age] (if (<= 13 age 19) "Teenager" "A normal person"))

(classify 18) ; "Teenager"

Page 37: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

(defn factorial [n] (if (= n 1) 1 (* n (factorial (- n 1)))))

Page 38: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

(defn fib [n] (cond (= n 0) 1 (= n 1) 1 :else (+ (fib (- n 1)) (fib (- n 2)))))

Page 39: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

(fn [x] (* x 2))

Page 40: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

(map (fn [n] (str "Mr. " n)) ["Anderson" "Bond" "Bean"])

; ("Mr. Anderson”; "Mr. Bond" ; "Mr. Bean")

Page 41: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

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

Page 42: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

(defn prime? [n] (not-any? (fn [x] (zero? (rem n x))) (range 2 (inc (Math/sqrt n)))))

Page 43: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

Data Structures

Page 44: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

maps (hashes)vectors (arrays)

sets

Page 45: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

immutable

Page 46: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

“Modifying” a structure creates a copy containing the change.

The original remains unmodified.

Page 47: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

Y

Page 48: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

simplicity

Page 49: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

multicore ❤ immutable

Page 50: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

persistent

Page 51: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

The “originals” are maximally reused

Page 52: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

a ! (3 2 1)

Page 53: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

123

a

a ! (3 2 1)

Page 54: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

a ! (3 2 1)b ! (conj a 4) (4 3 2 1)

Page 55: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

123

a

a ! (3 2 1)b ! (4 3 2 1)

4b

5cc ! (conj a 5)

Page 56: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

Hash Table

1020394597

1020205863

{:foo first, :bar second}

first

second

Page 57: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

Hash Table

1020394597

1020205863

Hash Table

1020394597

1020205863

1021027443

(conj table :qux 1024)

Page 58: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

not that simple

Page 59: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

Vectors(“arrays” in other langs)

Page 60: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

Vectors are represented by treesEach node has 32 children

Page 61: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

log32…

Page 62: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

… ⨯

Page 63: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

O(?)

Page 64: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

log32n

Page 65: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

325 = 33 554 432

326 = 1 073 741 824

Page 66: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

“essentially constant time”

Page 67: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015
Page 68: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

Software Transactional Memory

Page 69: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

concurrency 101

Page 70: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

100 € +50 € ⨯2

How much money will the account have?

Page 71: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

300 €250 €

Page 72: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

100 €

+50 € = 150 €

x2 = 300 €

Page 73: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

100 €

x2 = 200 €

+50 € = 250 €

Page 74: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

100 €

200 €

150 €x2+50

100 €100 €

Page 75: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

100 €

150 €

200 €

x2+50

100 €100 €

Page 76: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

ref

Page 77: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

state mutation is modelled as a transaction

Page 78: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

if two transactions “get in each others’

way”, one of them will restart

Page 79: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

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

Page 80: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

100 €

300 €

150 €x2 +50100 €

100 €

X

x2150 €

Page 81: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

Y

Page 82: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

familiar

Page 83: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

safe, easy, no deadlocks

Page 84: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

Macros

Page 85: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

Powerful instrument allowing expressive code

Page 86: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

Also known as:the mother of all metaprogramming

Page 87: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

MacroCodeSome other

code

Page 88: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015
Page 89: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

doStuff();

Page 90: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

Outputs on STDOUT. We want to have the result in a string instead.

Page 91: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

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

Page 92: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

(do-stuff)

Page 93: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

(with-out-str (do-stuff))

Page 94: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

(with-out-str (do-stuff))

Page 95: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

String output = withOutStr { doStuff();}

Page 96: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

unless

Page 97: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

(unless (hungry?) (sleep) (eat))

(if (not (hungry?)) (sleep) (eat))

Page 98: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

(defmacro unless [condition consequent alternative] `(if (not ~condition) ~consequent ~alternative))

Page 99: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

unless (isHungry()) { sleep();} else { eat();}

Page 100: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

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

Page 101: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

DSLDomain Specific Languages

Page 102: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

Transparency

Page 103: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

(source if-let)(source await)

Page 104: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

ClojureScript

Page 105: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

om

Page 106: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

Very dynamic

Page 107: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

DEMO

Page 108: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015

REPL Oriented Programming

Page 109: Stefan Kanev: Clojure, ClojureScript and Why They're Awesome at I T.A.K.E. Unconference 2015