Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23...

109
Clojure Lisp for the Real World @stuartsierra clojure.com

Transcript of Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23...

Page 1: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

ClojureLisp for the Real World

@stuartsierraclojure.com

Page 2: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

Stuart SierraRelevance, Inc.

Clojure/core

Clojure contributor

Page 3: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

Values

Page 4: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

Values

3

Page 5: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

Values

3 + 2 = 5

Page 6: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

Values

3let x =

Page 7: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

Values

3let x =

let x = 5

Page 8: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

Values

3let = 5

Page 9: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

Values

3define = 5

Page 10: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

Values

3

Page 11: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

Values

3Immutable

Page 12: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

Values

3Immutable Persistent

Page 13: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

He ll o, world!" "

Page 14: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

H e ll o , w o r l d ! \0

greeting

char greeting[14];strcpy(greeting, "Hello, World!");

Page 15: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

H e ll o , w o r l d ! \0

greeting

char* name = greeting + 7;

name

Page 16: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

H e ll o , b o r e d ! \0

greeting

name[0] = 'b';name[3] = 'e';

name

Page 17: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

String greeting = new String("Hello, world!");

H e ll o , w o r l d !

java.lang.String

greeting

Page 18: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

H e ll o , w o r l d !

java.lang.String

greeting

H e ll o , b o r e d !

java.lang.String

String alt = greeting.replace("world", "bored");

alt

Page 19: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

H e ll o , w o r l d !

java.lang.String

greeting

Immutable

Page 20: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

In the real world,values don't change.

Page 21: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

Clojure Values

3 Long

6.022e23 Double

"Hello, world!" String

3.0M BigDecimal

9223372036854775808N BigInt

2/3 Ratio

Page 22: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

Clojure Values

even? Symbol

:last-name Keyword

(print 99 "bottles") List

[3.14 :pi] Vector

{:x 3, "y" 4} Map

#{7 9 "foo"} Set

Page 23: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

Clojure Values

ListO(1) at the head

O(n) anywhere else

Vector O(1) access

Map O(1) access

Set O(1) contains?

*

*

*

Page 24: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

Immutable Persistent

Clojure Values(1 2 3)

[:a :b :c]

{:a 4}

#{3 7}

Page 25: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

x

...

Page 26: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

y x

...

Page 27: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

x

...

Page 28: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

x

...

y

...

Page 29: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

x y

...

Page 30: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

...

...

Page 31: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

...

...

...

...

Page 32: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

Clojure Values

ListO(1) at the head

O(n) anywhere else

Vector O(log32n) access

Map O(log32n) access

Set O(log32n) contains?

Page 33: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

321 = 32322 = 1024323 = 32,768324 = 1,048,576325 = 33,554,432326 = 1,073,741,824327 = 34,359,738,368

Page 34: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

log32 1000 < 2log32 10,000 < 3

log32 1,000,000 < 4log32 10,000,000 < 5

log32 1,000,000,000 < 6

Page 35: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

In the real world,log32n is fast enough.

Page 36: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

Code is Data

Page 37: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

#{ {:first "Stuart" :last "Sierra"} {:first "Luke" :last "VanderHart"} {:first "Michael" :last "Fogus"} }

Code is Data

Page 38: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

#{ {:first "Stuart" :last "Sierra"} {:first "Luke" :last "VanderHart"} {:first "Michael" :last "Fogus"} }

Code is Data

A set of maps

Page 39: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

(+ 3 4 5)List

Symbol

Page 40: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

(+ 3 4 5)List

Symbol

Function call

Page 41: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

(defn average [& nums] (/ (reduce + nums) (count nums)))

(average 3 4 5)

ListSymbols

VectorSymbols

Function call

Page 42: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

Host Interop.

(def m (ConcurrentHashMap. 100))

(.put m "key" "value")

constructor

method call

Page 43: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

You

Lexer/Parser

Characters

AbstractSyntax Tree

Compiler/Interpreter

Page 44: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

Clojure Reader

ClojureCompiler

You Characters

Data Structures

JVM Bytecode

Page 45: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

Clojure Reader

You Characters

Data Structures

Macros

ClojureCompiler

JVM Bytecode

Page 46: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

(let [file ...initializer...] (try ... do something ... (finally (.close file))))

Page 47: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

(defmacro with-open [bindings & body] `(let ~bindings (try ~@body (finally (.close ~(first bindings)))))

Page 48: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

(let [file ...initializer...] (try ... do something ... (finally (.close file))))

Page 49: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

(with-open [file ...initializer...] ... do something ...)

Page 50: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

Generic Data Access

Page 51: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

#{ {:first "Stuart" :last "Sierra"} {:first "Luke" :last "VanderHart"} {:first "Michael" :last "Fogus"} }

Generic data access

A set of maps

Page 52: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

Author[] authors = ...

String names[] = new names[authors.length];for (int i = 0; i < authors.length; i++) { names[i] = authors[i].getFirstName();}

Page 53: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

(defn get-first-name [author] (get author :first))

(map get-first-name authors)("Stuart" "Luke" "Michael")

Higher-orderfunction

Page 54: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

(map (fn [a] (get a :first)) authors)("Stuart" "Luke" "Michael")

Anonymous function

Page 55: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

(map #(get % :first) authors)("Stuart" "Luke" "Michael")

Anonymous function

Page 56: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

(map #(% :first) authors)("Stuart" "Luke" "Michael")

Maps are functions

Page 57: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

(map #(:first %) authors)("Stuart" "Luke" "Michael")

Keywords are functions!

Page 58: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

(map :first authors)("Stuart" "Luke" "Michael")

Keywords are functions

Page 59: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

(map :first authors)

String names[] = new names[authors.length];for (int i = 0; i < authors.length; i++) { names[i] = authors[i].getName();}

vs.

Page 60: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

(map function set-of-maps)

Page 61: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

(map function set-of-maps)(map function vector-of-sets-of-maps)(map function list-of-vectors)(map function map-of-maps)

Page 62: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

(map function set-of-maps)

(map function (resultset-seq query))

(map function (line-seq file))(map function (xml-seq xml-tree))

(map function (file-seq directory))

(map function list-of-vectors)(map function map-of-maps)

(map function vector-of-sets-of-maps)

Page 63: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

mapfilter

reducecountsome

removereplace

Sequence API

and lots more...

ListVectorMap

ResultSetStream

DirectoryIterator

XML

and lots more...

Sequence Generators

Page 64: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

mapfilter

reducecountsome

removereplace

Sequence API

and lots more...

ListVectorMap

ResultSetStream

DirectoryIterator

XML

and lots more...

Sequence Generators

× = Power

Page 65: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

Polymorphism

or, OOP: the Good Parts

Page 66: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

Multimethods(defmulti encounter (fn [a b] ... food chain comparison ...))

(defmethod encounter [:predator :predator] [a b] (fight a b))

(defmethod encounter [:predator :prey] [a b] (eat a b))

(defmethod encounter [:prey :predator] [a b] (eat b a))

(defmethod encounter [:prey prey] [a b] (run-away a) (run-away b))

Page 67: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

Protocols(defprotocol Coercions "Coerce between various 'resource-namish' things." (as-file [x] "Coerce argument to a file.") (as-url [x] "Coerce argument to a URL."))

(extend-protocol Coercions nil (as-file [_] nil) (as-url [_] nil) String (as-file [s] (File. s)) (as-url [s] (URL. s)) File (as-file [f] f) (as-url [f] (.toURL (.toURI f))))

Page 68: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

Records(def me {:name "Stuart" :state "NY" :city "Brooklyn"})

(type me) clojure.lang.PersistentHashMap

(:city me) "Brooklyn"

(defrecord Person [name state city])

(def me (->Person "Stuart" "NY" "Brooklyn"))

(type me) user.Person

(:city me) "Brooklyn"

Page 69: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

Record + Protocols(defprotocol Coercions "Coerce between various 'resource-namish' things." (as-file [x] "Coerce argument to a file.") (as-url [x] "Coerce argument to a URL."))

(defrecord MyResource [protocol host path] Coercions (as-file [x] (java.io.File. path)) (as-url [x] (java.io.URL. (str protocol "://" host "/" path))))

Page 70: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

Records(defrecord Person [name state city])

(def me (->Person "Stuart" "NY" "Brooklyn"))

(type me) user.Person

(:city me) "Brooklyn"

(ancestors (type me)) #{clojure.lang.IPersistentCollection java.io.Serializable clojure.lang.Associative clojure.lang.IPersistentMap clojure.lang.IKeywordLookup clojure.lang.IMeta clojure.lang.IObj java.util.Map java.lang.Iterable clojure.lang.Counted clojure.lang.IRecord clojure.lang.ILookup java.lang.Object clojure.lang.Seqable}

Page 71: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

Types

(deftype SuperNewTree [size root])

(def me (->SuperNewTree 0 nil))

(type me) user.SuperNewTree

(ancestors (type me)) #{clojure.lang.IType java.lang.Object}

Page 72: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

Existing Protocolsor Interfaces

Your newprotocol here

Existing Types

Existing Method Implementations

extend(very hard in Java)

Your new type here

extend

The Expression Problem

Page 73: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

Concurrency

Page 74: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

Concurrency

Parallelism

State

Page 75: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

class Invoice { private Date date;

public Date getDate() { return this.date; }

public void setDate(Date date) { this.date = date; }}

Page 76: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

class Date { public void setDay(int day); public void setMonth(int month); public void setYear(int year);}

Mutable!

Page 77: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

class Invoice { private Date date;

public Date getDate() { return this.date; }

public void setDate(Date date) { this.date = date; }}

Better notchange it!

Better notchange it!

Page 78: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

class Invoice { private Date date;

public Date getDate() { return this.date.clone(); }

public void setDate(Date date) { this.date = date.clone(); }}

Defensivecopying

Page 79: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

Programming with immutable values

means never having to say you're sorry.

Page 80: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

today

June 20

Page 81: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

today

June 20 June 21

Page 82: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

Identity

State

today

Value Value

June 20 June 21

Page 83: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

Identity

State

today

function

Value Value

functionJune 20 June 21

Page 84: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

Identity

State

Past

function

Present Future

function

today

June 20 June 21June 19

Page 85: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

June 20

Identity

State

Past

June 21June 19 function

Present Future

function

today

The future is a function of the past.

Page 86: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

Mutable References

Ref Atom

Var Agent

Page 87: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

readers

Atomwriter

writer

abortretry spin

commit

Page 88: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

Atom(def tick (atom 1))(deref tick) 1

tick

1

Page 89: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

Atom(def tick (atom 1))(deref tick) 1

(swap! tick inc)@tick 2

tick

1

2

inc

Page 90: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

Atom(def tick (atom 1))(deref tick) 1

(swap! tick inc)@tick 2

(swap! tick + 10)@tick 12

tick

2

12

+10

Page 91: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

value value value value

value value value value

value value value value

identity

identityidentity

Page 92: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

value value value value

value value value value

value value value value

identity

identityidentity

Page 93: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

Refwriter

writer

readers

abortretryRef

transaction

wait

commit

Page 94: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

Ref(def A (ref 1))(def B (ref 10))

A 1

10B

Page 95: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

Ref(def A (ref 1))(def B (ref 10))

(dosync (alter A inc) (alter B + 10))

A 1

10

20

inc

+10

B

2

transaction

Page 96: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

Ref(def A (ref 1))(def B (ref 10))

(dosync (alter A inc) (alter B + 10))

A

20

B

2

@A 2@B 20

Page 97: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

AtomicConsistentIsolatedDurable

Database Transactions

Page 98: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

AtomicConsistentIsolated

Clojure Transactions

Page 99: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

Agentactionaction

readers

action queue

Agent Thread Pool

Page 100: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

Agent(def A (agent 1))

A 1queue

Page 101: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

Agent(def A (agent 1))

(send A inc)@A 1

A 1inc

queue

Page 102: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

Agent(def A (agent 1))

(send A inc)@A 1

A 1inc

2@A 2

queue

Page 103: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

Agents != Actors

Page 104: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

Agents != Actors

Agent Actor

Reads

Actions / Messages

Distributed?

Cheap,do not block

Send message,wait for response

Any functionOnly what receiver

understands

No Yes

Page 105: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

Agents != Actors

Agent Actor

Reads

Actions / Messages

Distributed?

Cheap,do not block

Send message,wait for response

Any functionOnly what receiver

understands

No Yes

Page 106: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

Agents != Actors

Agent Actor

Reads

Actions / Messages

Distributed?

Cheap,do not block

Send message,wait for response

Any functionOnly what receiver

understands

No Yes

Page 107: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

Agents != Actors

Agent Actor

Reads

Actions / Messages

Distributed?

Cheap,do not block

Send message,wait for response

Any functionOnly what receiver

understands

No Yes

Page 108: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

Ref Atom

Var Agent

Concurrency

• No locking in user code

• No deadlocks

• Guaranteed forward progress

• Writes never block reads

Page 109: Clojure Lisp for the Real World - YOW! Conferences · 2019-09-23 · Clojure Values 3 Long 6.022e23 Double "Hello, world!" String 3.0M BigDecimal 9223372036854775808N BigInt 2/3 Ratio

More

• Me: stuartsierra.com,@stuartsierra

• Us: thinkrelevance.com,clojure.com

• Clojure: clojure.org

Image Credits: openclipart.org, pdtextures.blogspot.com,Clojure logo by Tom Hickey