Transcript
Page 1: Software Dendrology by Brandon Bloom

!

Dendrology Brandon Bloom

Page 2: Software Dendrology by Brandon Bloom

!

Dendrology Brandon Bloom

Page 3: Software Dendrology by Brandon Bloom

bbloom: better ways to analyze and process trees is a bit of a new obsession of mine :-) gfredericks: clojurebot: bbloom is a dendrologist clojurebot: Alles klar

once upon a time in #clojure…

Page 4: Software Dendrology by Brandon Bloom

Assumptions

Data

Immutability

Values

Page 5: Software Dendrology by Brandon Bloom
Page 6: Software Dendrology by Brandon Bloom
Page 7: Software Dendrology by Brandon Bloom
Page 8: Software Dendrology by Brandon Bloom

A

B C D

E F G

Page 9: Software Dendrology by Brandon Bloom

A

B C D

E F G

Page 10: Software Dendrology by Brandon Bloom

A

B C D

E F G

Page 11: Software Dendrology by Brandon Bloom

A B C D

Page 12: Software Dendrology by Brandon Bloom

A

B C

D

Page 13: Software Dendrology by Brandon Bloom

A

B C

D D

Page 14: Software Dendrology by Brandon Bloom

A

B C

D

Page 15: Software Dendrology by Brandon Bloom

A

B C

D

Page 16: Software Dendrology by Brandon Bloom
Page 17: Software Dendrology by Brandon Bloom
Page 18: Software Dendrology by Brandon Bloom

the of allPointer cycles are root evil.tail

Page 19: Software Dendrology by Brandon Bloom

Pointer cycles are evil.

Page 20: Software Dendrology by Brandon Bloom

A

B C

D

B[D]⇒B[E]

Page 21: Software Dendrology by Brandon Bloom

A

B C

D

B[D]⇒B[E]

A’

B’

E

Page 22: Software Dendrology by Brandon Bloom

A

B C

D

B[D]⇒B[E]

Page 23: Software Dendrology by Brandon Bloom

A

B C

D

B[D]⇒B[E]

A

B C

D

B[D]⇒B[E]

A’

B’ C’

E

Page 24: Software Dendrology by Brandon Bloom

D

G

A

B C

E F H I J

Page 25: Software Dendrology by Brandon Bloom

D

G

A

B C

E F H I J

G⇒G’

Page 26: Software Dendrology by Brandon Bloom

D’

G’

A’

B’ C’

E’ F’ H’ I’ J’

G⇒G’

Page 27: Software Dendrology by Brandon Bloom

Pointer are evil. cycles

Page 28: Software Dendrology by Brandon Bloom

Pointer are evil.s

Page 29: Software Dendrology by Brandon Bloom

A

B C

D

B⇒B’

Page 30: Software Dendrology by Brandon Bloom

A

B C

D

B⇒B’

A’

B’

Page 31: Software Dendrology by Brandon Bloom

A

B C

D

B⇒B’

A’

B’

Page 32: Software Dendrology by Brandon Bloom

A

B C

D

B⇒B’

A’

B’

Page 33: Software Dendrology by Brandon Bloom

A

B C

D

B⇒B’

A’

B’

B’⇒B’’

A’’

B’’

Page 34: Software Dendrology by Brandon Bloom
Page 35: Software Dendrology by Brandon Bloom

A

B C

D

B⇒B’

A’

B’

B’⇒B’’

A’’

B’’

Page 36: Software Dendrology by Brandon Bloom

Let’s talk about pointers and identities.

Page 37: Software Dendrology by Brandon Bloom

static byte memory[MEMORY_SIZE];!!template <class T>!class Pointer {!!public:!! Pointer(long p) {! _p = p;! }!! T deref() const {! return !@#$%(memory + _p);! }!! Pointer<T> add(int n) const {! return Pointer(_p + n * sizeof(T));! }!!private:!! long _p;!!};

Page 38: Software Dendrology by Brandon Bloom

static byte memory[MEMORY_SIZE];!!template <class T>!class Reference {!!public:!! Reference(long p) {! _p = p;! }!! T deref() const {! return !@#$%(memory + _p);! }!!!!!!private:!! long _p;!!};

Page 39: Software Dendrology by Brandon Bloom

!!template <class T>!class Reference {!!public:!! Reference(long p) {! _p = p;! }!! T deref() const {! return !@#$%(memory + _p);! }!!!!!!private:!! long _p;!!};

Page 40: Software Dendrology by Brandon Bloom

template <class T>!class Reference {!!public:!! Reference(long p, byte *memory) {! _p = p;! _memory = memory;! }!! T deref() const {! return !@#$%(_memory + _p);! }!!private:!! long _p;! long _memory;!!};

Page 41: Software Dendrology by Brandon Bloom

template <class T>!class Reference {!!public:!! Reference(long p) {! _p = p;! }!! T deref(const byte *const memory) const {! return !@#$%(memory + _p);! }!!private:!! long _p;!!};

Page 42: Software Dendrology by Brandon Bloom

(defprotocol IDeref! (deref [this]))

(deftype Reference [p]! IDerefIn! (deref-in [_ memory]! (!$%&* memory p)))

(defprotocol IDerefIn! (deref-in [this context]))

Page 43: Software Dendrology by Brandon Bloom

(deftype DbRef [table id]! (deref-in [_ db]! (get-row db table id)))!!(let [brandon (DbRef. :users 5)]! (deref-in brandon *db*))!!(defn get-user [db id]! (get-row db :users id))!!(let [brandon 5]! (get-user *db* brandon)

Page 44: Software Dendrology by Brandon Bloom

"http://example.com/api/users/5”

Page 45: Software Dendrology by Brandon Bloom

[:user 5]

Page 46: Software Dendrology by Brandon Bloom

5

Page 47: Software Dendrology by Brandon Bloom

Context is King

Page 48: Software Dendrology by Brandon Bloom

(def x "top-level")!!(fn []! x! (let [x "local"]! x))!

cljs.user.x = "top-level";!!function () {! cljs.user.x;! var x = "local";! return x;!}

Symbols: The Original Identities

var

local symbol resolved using context!

Page 49: Software Dendrology by Brandon Bloom

(def x "top-level")!!(fn []! x! (let [x "local"]! x))!

cljs.user.x = "top-level";!!function () {! cljs.user.x;! var x = "local";! return x;!}

Context: Not Just For Identities

statement

tail position contextual return!

Page 50: Software Dendrology by Brandon Bloom

(def vector-tree! ["A" ["B" ["E"] ["F"]] ["C"] ["D" ["G"]]])

A

B C D

E F G

(def tree! {:label "A"! :children [{:label "B"! :children [{:label "E"}! {:label "F"}]}! {:label "C"}! {:label "D"! :children [{:label "G"}]}]})

Page 51: Software Dendrology by Brandon Bloom

(defn annotate-depth [node]!!!!!!!!!

A

B C D

E F G

0!!

1!!

2

! (letfn [(f [node depth]! (let [d (inc depth)! annotate-child #(f % d)]! (-> node! (assoc :depth depth)! (update-in! [:children]! (mapv annotate-child %)))))]! (f node 0)))

Page 52: Software Dendrology by Brandon Bloom

A

B C D

E F G

2

2

2 2

1 2

2

(defn annotate-max-depth [node]!!!!!!!!!!

! (let [{:keys [children]} node]! (if (seq children)! (let [children*! (mapv annotate-max-depth children)]! (assoc node! :max-depth (apply max! (map :max-depth children*))! :children children*))! (assoc node :max-depth (:depth node)))))

Page 53: Software Dendrology by Brandon Bloom

A

B C D

E F G

0

1

2 3

4 5

6

(defn print-depth-first-recursive [node]! (letfn [(f [node index]! (println index (:label node))! (loop [nodes (:children node)! i index]! (if (seq nodes)! (recur (next nodes)! (f (first nodes) (inc i)))! i)))]! (f node 0))! nil)

0 A 1 B 2 E 3 F 4 C 5 D 6 G

Page 54: Software Dendrology by Brandon Bloom

A

B C D

E F G

0

1

2 3

4 5

6

(defn number-depth-first-recursive [node]! (letfn [(f [node index]! (let [[max-index children*]! (reduce (fn [[i children] child]! (let [child* (f child (inc i))! i* (:max-index child*)]! [i* (conj children child*)]))! [index []]! (:children node))]! (assoc node! :index index! :children children*! :max-index max-index)))]! (f node 0)))

Page 55: Software Dendrology by Brandon Bloom

A

B C D

E F G

0

1

2 3

4 5

6

(defn number-depth-first-stateful [node]! (let [index (atom 0)]! ((fn rec [n]! (let [i @index]! (swap! index inc)! (-> n! (assoc :index i)! (update-in [:children] #(mapv rec %)))))! node)))

Page 56: Software Dendrology by Brandon Bloom

(defn print-depth-first-iterative [node]! (loop [index 0! nodes (list node)]! (when (seq nodes)! (let [[node & nodes*] nodes]! (println index (:label node))! (recur (inc index)! (concat (:children node)! nodes*))))))

A

B C D

E F G

0

1

2 3

4 5

6

Page 57: Software Dendrology by Brandon Bloom

(defn print-breadth-first-iterative [node]! (loop [index 0! nodes (list node)]! (when (seq nodes)! (let [[node & nodes*] nodes]! (println index (:label node))! (recur (inc index)! (concat nodes*! (:children node)))))))

A

B C D

E F G

0

1

4 5

2 3

6

0 A 1 B 2 C 3 D 4 E 5 F 6 G

Page 58: Software Dendrology by Brandon Bloom

A

B C D

E F G

0

1

2 3

4 5

6

(defn make-zipper [root]! (z/zipper (fn branch? [n]! true)! :children! (fn make-node [n children]! (assoc n :children (vec children)))! root))

Page 59: Software Dendrology by Brandon Bloom

A

B C D

E F G

0

1

2 3

4 5

6

(defn number-depth-first-zipper [node]! (loop [index 0! loc (make-zipper node)]! (if (z/end? loc)! (z/root loc)! (let [loc* (z/edit loc assoc :index index)]! (recur (inc index) (z/next loc*))))))

complete context as data!

Page 60: Software Dendrology by Brandon Bloom

Melt your brain: !Breadth-first numbering!Chris Okasaki !Backtracking Iterators!Jean-Christophe Filliâtre

A

B C D

E F G

0

1

4 5

2 3

6

Page 61: Software Dendrology by Brandon Bloom

Carefully consider: identities + contexts

Page 62: Software Dendrology by Brandon Bloom
Page 63: Software Dendrology by Brandon Bloom
Page 64: Software Dendrology by Brandon Bloom

EXTRA SLIDES PAST HERE

Page 65: Software Dendrology by Brandon Bloom

let cyclic = let x = 0 : y! y = 1 : x! in x!!take 10 cyclic!-- [0,1,0,1,0,1,0,1,0,1]

(def cyclic! (letfn [(x [] (cons 0 (lazy-seq (y))))! (y [] (cons 1 (lazy-seq (x))))]! (x)))!!(take 10 cyclic)!;=> (0 1 0 1 0 1 0 1 0 1)

A note about laziness

Page 66: Software Dendrology by Brandon Bloom

(def cyclic! (letfn [(x [] (cons 0 (lazy-seq (y))))! (y [] (cons 1 (lazy-seq (x))))]! (x)))!!(take 10 cyclic)!;=> (0 1 0 1 0 1 0 1 0 1)

(def cyclic! (letfn [(x [] (cons 0 (new clojure.lang.LazySeq! (fn [] (y)))))! (y [] (cons 1 (new clojure.lang.LazySeq! (fn [] (x)))))]! (x)))


Recommended