Joseph Wilk The Clojure Inside Why Clojure? It was Functional - - PowerPoint PPT Presentation

joseph wilk the clojure inside why clojure it was
SMART_READER_LITE
LIVE PREVIEW

Joseph Wilk The Clojure Inside Why Clojure? It was Functional - - PowerPoint PPT Presentation

Joseph Wilk The Clojure Inside Why Clojure? It was Functional Immutable there! Simple LISP Concurrency It was Functional Immutable there! Simple LISP Concurrency Programming Language Computer LISP Hurts (Pick languages that


slide-1
SLIDE 1

Joseph Wilk

slide-2
SLIDE 2

The Clojure Inside

slide-3
SLIDE 3
slide-4
SLIDE 4

Why Clojure?

slide-5
SLIDE 5

LISP Concurrency Immutable Functional Simple

It was there!

slide-6
SLIDE 6

LISP Concurrency Immutable Functional Simple

It was there!

slide-7
SLIDE 7

Programming Language Computer

slide-8
SLIDE 8

LISP Hurts

(Pick languages that challenge your mental model) (( ))

slide-9
SLIDE 9

(defn filter "Returns a lazy sequence of the items in coll for which (pred item) returns true. pred must be free of side-effects." {:added "1.0" :static true} ([pred coll] (lazy-seq (when-let [s (seq coll)] (if (chunked-seq? s) (let [c (chunk-first s) size (count c) b (chunk-buffer size)] (dotimes [i size] (when (pred (.nth c i)) (chunk-append b (.nth c i)))) (chunk-cons (chunk b) (filter pred (chunk-rest s)))) (let [f (first s) r (rest s)] (if (pred f) (cons f (filter pred r)) (filter pred r))))))))

slide-10
SLIDE 10 (defmacro doseq "Repeatedly executes body (presumably for side-effects) with bindings and filtering as provided by \"for\". Does not retain the head of the sequence. Returns nil." {:added "1.0"} [seq-exprs & body] (assert-args (vector? seq-exprs) "a vector for its binding" (even? (count seq-exprs)) "an even number of forms in binding vector") (let [step (fn step [recform exprs] (if-not exprs [true `(do ~@body)] (let [k (first exprs) v (second exprs)] (if (keyword? k) (let [steppair (step recform (nnext exprs)) needrec (steppair 0) subform (steppair 1)] (cond (= k :let) [needrec `(let ~v ~subform)] (= k :while) [false `(when ~v ~subform ~@(when needrec [recform]))] (= k :when) [false `(if ~v (do ~subform ~@(when needrec [recform])) ~recform)])) (let [seq- (gensym "seq_") chunk- (with-meta (gensym "chunk_") {:tag 'clojure.lang.IChunk}) count- (gensym "count_") i- (gensym "i_") recform `(recur (next ~seq-) nil 0 0) steppair (step recform (nnext exprs)) needrec (steppair 0) subform (steppair 1) recform-chunk `(recur ~seq- ~chunk- ~count- (unchecked-inc ~i-))

wee wee

wee wee wee wee wee

wee wee

Code generation Code is data Data is code Functions what do functions Variable generation Is that a class?

slide-11
SLIDE 11

OH MY ITS FAST

(Jetty/Netty but sssssh) (Shhh confirmation Bias)
slide-12
SLIDE 12

History

slide-13
SLIDE 13

Rails Me

slide-14
SLIDE 14

Rails Me

slide-15
SLIDE 15

Ruby

slide-16
SLIDE 16

Small Replaceable Pieces

slide-17
SLIDE 17

Experiment

A B ?

Opening (Divergent) Exploring (Emergent) Closing (Convergent)

slide-18
SLIDE 18

Clojure

slide-19
SLIDE 19

Hystrix Turbine RxJava Netty Aleph Compojure

https://github.com/Netflix/Hystrix https://github.com/Netflix/Turbine https://github.com/Netflix/RxJava https://github.com/ztellman/aleph https://github.com/weavejester/compojure http://netty.io

Midje

https://github.com/marick/Midje

Ring

https://github.com/ring-clojure/ring

slide-20
SLIDE 20

Maturity Brevity + & Denial (its not Java)

slide-21
SLIDE 21

atom quote eq car cdr cons cond lambda label apply

slide-22
SLIDE 22

Java Denial

(defmacro)
slide-23
SLIDE 23

HttpServer server = HttpServer.create(address, 0) server.createContext(path, handler); server.setExecutor(null) server.start(); (doto (HttpServer/create address 0) (.createContext path handler) (.setExecutor nil) (.start))

slide-24
SLIDE 24

HttpServer server = HttpServer.create(address, 0) server.createContext(path, handler); server.setExecutor(null) server.start(); (doto (HttpServer/create address 0) (.createContext path handler) (.setExecutor nil) (.start))

slide-25
SLIDE 25

public class GetSoundCmd extends HystrixCommand<Sound> { private final HttpClient client; private final String urn; public FindSoundCmd(HttpClient client, String urn){ this.client = client; this.urn = urn; } @Override protected Sound run(){ return client.get("/sounds/" + urn, Sound.class) } @Override protected Sound getFallback(){ return Sound.missing(id); } } new GetUserCmd(client, id).execute(); (:require [com.netflix.hystrix.core :as hystrix]) (hystrix/defcommand find-sound {:hystrix/fallback-fn #(constantly {}))} [client urn] (http/get urn)) (get-sound client "soundcloud:sounds:123")

slide-26
SLIDE 26

public class GetSoundCmd extends HystrixCommand<Sound> { private final HttpClient client; private final String urn; public FindSoundCmd(HttpClient client, String urn){ this.client = client; this.urn = urn; } @Override protected Sound run(){ return client.get("/sounds/" + urn, Sound.class) } @Override protected Sound getFallback(){ return Sound.missing(id); } } new GetUserCmd(client, id).execute(); (:require [com.netflix.hystrix.core :as hystrix]) (hystrix/defcommand find-sound {:hystrix/fallback-fn #(constantly {}))} [client urn] (http/get urn)) (get-sound client "soundcloud:sounds:123")

slide-27
SLIDE 27

Interactivity

R read E evaluate P print L loop

slide-28
SLIDE 28
slide-29
SLIDE 29

Services at scale

slide-30
SLIDE 30
slide-31
SLIDE 31

Grace in the face of failure

high partition tolerance in a high latency cloud network (don't trust anything works)
slide-32
SLIDE 32

Threadpool (future (fn [] "from the future")) (promise) (agent)

slide-33
SLIDE 33
slide-34
SLIDE 34
slide-35
SLIDE 35
slide-36
SLIDE 36
slide-37
SLIDE 37

Threadpool 100 threads

Bulkhead

Threadpool 10 threads Threadpool 10 threads Threadpool 30 threads Scheduler queue

slide-38
SLIDE 38

(hystrix/defcommand find-user {:hystrix/fallback-fn (constantly {})} [user-urn] (let [response (get-user user-urn)] (if (= 200 (:status response)) (:body response) {}))) (find-user 123) (hystrix/queue #‘find-user 123) (defn find-user [user-urn] (let [response (get-user user-urn)] (if (= 200 (:status response)) (:body response) {})))

slide-39
SLIDE 39

(hystrix/defcommand find-user {:hystrix/fallback-fn (constantly {})} [user-urn] (let [response (get-user user-urn)] (if (= 200 (:status response)) (:body response) {}))) (find-user 123) (hystrix/queue #‘find-user 123) (defn find-user [user-urn] (let [response (get-user user-urn)] (if (= 200 (:status response)) (:body response) {})))

slide-40
SLIDE 40

(hystrix/defcommand find-user {:hystrix/fallback-fn (constantly {})} [user-urn] (let [response (get-user user-urn)] (if (= 200 (:status response)) (:body response) {}))) (find-user 123) (hystrix/queue #‘find-user 123) (defn find-user [user-urn] (let [response (get-user user-urn)] (if (= 200 (:status response)) (:body response) {})))

slide-41
SLIDE 41

Consumers

Service X

Turbine DNS Dashboard

Service X Service X Service X Service X

metrics discovery

slide-42
SLIDE 42 https://github.com/Netflix/Hystrix
slide-43
SLIDE 43
slide-44
SLIDE 44

Compositional Complexity

slide-45
SLIDE 45

a c b d g f e

slide-46
SLIDE 46

a c b d g f e

slide-47
SLIDE 47

a c b d g

zip map

List Processing

zip

e

slide-48
SLIDE 48

List Processing

a c b d g

zip map zip

e

slide-49
SLIDE 49

LisP

a c b d g

zip map zip

e

slide-50
SLIDE 50

RxJava

(map) (zip) (filter) (partition) (reduce)

https://github.com/Netflix/RxJava
slide-51
SLIDE 51

a c b d g

zip map zip

e

  • n-error
  • n-complete

Ending Callback Hell

(.subscribe (fn [result] (enqueue channel {:status 200 :body (json/encode result}) (fn [error] (log/exception error request))))))

slide-52
SLIDE 52 https://github.com/ztellman/aleph

Request & Response

(.subscribe (fn [result] (enqueue channel {:status 200 :body (json/encode result}) (fn [error] (log/exception error request)))))) (defn handler [request] {:status 200 :body "Hello World"}) (use 'lamina.core) (defn handler [response-channel request] (enqueue response-channel {:status 200 :body "Hello World"}))

slide-53
SLIDE 53 https://github.com/ztellman/aleph

Request & Response

(.subscribe (fn [result] (enqueue channel {:status 200 :body (json/encode result}) (fn [error] (log/exception error request)))))) (defn handler [request] {:status 200 :body "Hello World"}) (use 'lamina.core) (defn handler [response-channel request] (enqueue response-channel {:status 200 :body "Hello World"}))

slide-54
SLIDE 54 https://github.com/ztellman/aleph

Request & Response

(.subscribe (fn [result] (enqueue channel {:status 200 :body (json/encode result}) (fn [error] (log/exception error request)))))) (defn handler [request] {:status 200 :body "Hello World"}) (use 'lamina.core) (defn handler [response-channel request] (enqueue response-channel {:status 200 :body "Hello World"}))

slide-55
SLIDE 55 https://github.com/ztellman/aleph

Request & Response

(.subscribe (fn [result] (enqueue channel {:status 200 :body (json/encode result}) (fn [error] (log/exception error request)))))) (defn handler [request] {:status 200 :body "Hello World"}) (use 'lamina.core) (defn handler [response-channel request] (enqueue response-channel {:status 200 :body "Hello World"}))

slide-56
SLIDE 56

Clojure Itches

Its upside down attern matching Corrupts your brain parameter redeye

slide-57
SLIDE 57

Clojure

One of the many paths

slide-58
SLIDE 58

Joseph Wilk