cpl 2016, week 11 - clojure immutable data structures · 2016-04-25 · institute of computer...

39
CPL 2016, week 11 Clojure immutable data structures Oleg Batrashev Institute of Computer Science, Tartu, Estonia April 25, 2016

Upload: others

Post on 06-Jul-2020

1 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: CPL 2016, week 11 - Clojure immutable data structures · 2016-04-25 · Institute of Computer Science, Tartu, Estonia April25,2016. Overview Lastweek I Clojurelanguagecore ... I Softwaretransactionalmemory

CPL 2016, week 11Clojure immutable data structures

Oleg Batrashev

Institute of Computer Science, Tartu, Estonia

April 25, 2016

Page 2: CPL 2016, week 11 - Clojure immutable data structures · 2016-04-25 · Institute of Computer Science, Tartu, Estonia April25,2016. Overview Lastweek I Clojurelanguagecore ... I Softwaretransactionalmemory

Overview

Last weekI Clojure language core

This weekI Immutable data structures

Next weeksI Clojure simple state and designI Software transactional memoryI Agents in Clojure

Page 3: CPL 2016, week 11 - Clojure immutable data structures · 2016-04-25 · Institute of Computer Science, Tartu, Estonia April25,2016. Overview Lastweek I Clojurelanguagecore ... I Softwaretransactionalmemory

Immutable data structures 27/74 -

Trees

I (defrecord tree [value left right]) – Java class with 3immutable fields

I Having (tree. 3 :leaf (tree. 33 :leaf :leaf))

I want to replace 3 with 45

tree 3

leaf tree 33

leaf leaf

tree 45

I need to create new node and point to the subtreesI in general, path from root to node must be reconstructedI whoever references (part of) the tree never sees any changes

Page 4: CPL 2016, week 11 - Clojure immutable data structures · 2016-04-25 · Institute of Computer Science, Tartu, Estonia April25,2016. Overview Lastweek I Clojurelanguagecore ... I Softwaretransactionalmemory

Immutable data structures 27/74 -

Trees

I (defrecord tree [value left right]) – Java class with 3immutable fields

I Having (tree. 3 :leaf (tree. 33 :leaf :leaf))

I want to replace 3 with 45

tree 3

leaf tree 33

leaf leaf

tree 45

I need to create new node and point to the subtreesI in general, path from root to node must be reconstructedI whoever references (part of) the tree never sees any changes

Page 5: CPL 2016, week 11 - Clojure immutable data structures · 2016-04-25 · Institute of Computer Science, Tartu, Estonia April25,2016. Overview Lastweek I Clojurelanguagecore ... I Softwaretransactionalmemory

Immutable data structures 28/74 -

Immutable data structures

I “Purely functional data structures” (book)I immutable – whoever has reference never sees any changesI structural sharing – old instance shares data with the new oneI assymptotically (almost) as efficient as transient

implementationsI O(log32 n) for unsorted collections (vector,hash-map,hash-set)I O(log2 n) for sorted collections (sorted-map,sorted-set)

I in Clojure referred as persistent collections

I transient counterpartsI handy for local,temporary operations, like StringBuffer

Page 6: CPL 2016, week 11 - Clojure immutable data structures · 2016-04-25 · Institute of Computer Science, Tartu, Estonia April25,2016. Overview Lastweek I Clojurelanguagecore ... I Softwaretransactionalmemory

Immutable data structures 29/74 -

Benefits

I may be safelyI passed to functionsI used as keys in maps and entries in sets

I enabling concurrencyI sharing collections between threads is safe

I free versioningI old versions of the instance are untouched – may store them to

a sequence and use for undo

Page 7: CPL 2016, week 11 - Clojure immutable data structures · 2016-04-25 · Institute of Computer Science, Tartu, Estonia April25,2016. Overview Lastweek I Clojurelanguagecore ... I Softwaretransactionalmemory

Immutable data structures 30/74 Binary Tree -

Outline

Immutable data structuresBinary TreeWorking with immutable dataBinary search treeBalanced BSTOther algorithmsPersistent vector and map

Page 8: CPL 2016, week 11 - Clojure immutable data structures · 2016-04-25 · Institute of Computer Science, Tartu, Estonia April25,2016. Overview Lastweek I Clojurelanguagecore ... I Softwaretransactionalmemory

Immutable data structures 31/74 Binary Tree -

DefinitionI A node in binary tree can be either

I a leaf – :leafI an internal node – with left and right subtrees

(defrecord Node [value left right])

I Ex: (Node. 15 :leaf (Node. 33 :leaf :leaf))tree 15

leaf tree 33

leaf leaf

I More compactly15

33

Page 9: CPL 2016, week 11 - Clojure immutable data structures · 2016-04-25 · Institute of Computer Science, Tartu, Estonia April25,2016. Overview Lastweek I Clojurelanguagecore ... I Softwaretransactionalmemory

Immutable data structures 32/74 Binary Tree -

Depth-first traversal

I Traverse left subtree then right subtree

(defn dft [node](if (= node :leaf)

(println :leaf)(do

(println (.value node))(dft (.left node))(dft (.right node )))))

I by itself not specifically usefulI add accumulator

Page 10: CPL 2016, week 11 - Clojure immutable data structures · 2016-04-25 · Institute of Computer Science, Tartu, Estonia April25,2016. Overview Lastweek I Clojurelanguagecore ... I Softwaretransactionalmemory

Immutable data structures 33/74 Binary Tree -

DFT with accumulator

(defn - dft -acc -impl [node acc](if (= node :leaf)

acc(let [lAcc (dft -acc -impl (.left node) acc)

cAcc (cons (.value node) lAcc)rAcc (dft -acc -impl (.right node) cAcc)]

rAcc )))

(defn dft -acc [node](reverse (dft -acc -impl node '())))

I List accumulatorI grow from list headI reverse at the end

Page 11: CPL 2016, week 11 - Clojure immutable data structures · 2016-04-25 · Institute of Computer Science, Tartu, Estonia April25,2016. Overview Lastweek I Clojurelanguagecore ... I Softwaretransactionalmemory

Immutable data structures 34/74 Binary Tree -

Breadth-first traversal

1. put tree root node to a queue2. iteratively

2.1 take tree node from the queue2.2 process node2.3 put child nodes to the queue

I queue could be immutable (see below)

Page 12: CPL 2016, week 11 - Clojure immutable data structures · 2016-04-25 · Institute of Computer Science, Tartu, Estonia April25,2016. Overview Lastweek I Clojurelanguagecore ... I Softwaretransactionalmemory

Immutable data structures 35/74 Working with immutable data -

Outline

Immutable data structuresBinary TreeWorking with immutable dataBinary search treeBalanced BSTOther algorithmsPersistent vector and map

Page 13: CPL 2016, week 11 - Clojure immutable data structures · 2016-04-25 · Institute of Computer Science, Tartu, Estonia April25,2016. Overview Lastweek I Clojurelanguagecore ... I Softwaretransactionalmemory

Immutable data structures 36/74 Working with immutable data -

Accessing

I Having collection/object like (def d {:somekey 42}) access

(d :somekey)(: somekey d)(. somekey d)(get d :somekey)(get -in d [: somekey ])

1. works for lists and maps2. works for maps and records, may return nil

3. works for records/types/objects, may throwNullPointerException

4. works for lists, maps and records5. multilevel get, may specify list of keys for several levels

Page 14: CPL 2016, week 11 - Clojure immutable data structures · 2016-04-25 · Institute of Computer Science, Tartu, Estonia April25,2016. Overview Lastweek I Clojurelanguagecore ... I Softwaretransactionalmemory

Immutable data structures 37/74 Working with immutable data -

“Update” immutable state

(assoc d :newkey 43 :key3 44)(conj d [: newkey 43])(into d {: newkey 43})(assoc -in d [: newkey 2 3] 43)

; -> {: somekey 42, :newkey {2 {3 43}}}

1. assign new values, works with lists, maps, and records2. update elements, works with lists, maps3. update several elements (from another collection)4. multilevel update, works with maps and records

All of them return new object, because you are working onimmutable structures!

Page 15: CPL 2016, week 11 - Clojure immutable data structures · 2016-04-25 · Institute of Computer Science, Tartu, Estonia April25,2016. Overview Lastweek I Clojurelanguagecore ... I Softwaretransactionalmemory

Immutable data structures 38/74 Binary search tree -

Outline

Immutable data structuresBinary TreeWorking with immutable dataBinary search treeBalanced BSTOther algorithmsPersistent vector and map

Page 16: CPL 2016, week 11 - Clojure immutable data structures · 2016-04-25 · Institute of Computer Science, Tartu, Estonia April25,2016. Overview Lastweek I Clojurelanguagecore ... I Softwaretransactionalmemory

Immutable data structures 39/74 Binary search tree -

Definition

I binary search tree (ordered binary tree)I values in

I left subtree are smallerI right subtree are larger

15

6

3 8

33

Page 17: CPL 2016, week 11 - Clojure immutable data structures · 2016-04-25 · Institute of Computer Science, Tartu, Estonia April25,2016. Overview Lastweek I Clojurelanguagecore ... I Softwaretransactionalmemory

Immutable data structures 40/74 Binary search tree -

Lookup

(defn lookup [node v](if (= node :leaf)

:not -found(let [nodeV (.value node)]

(cond(= v nodeV) v(< v nodeV) (lookup (.left node) v)(> v nodeV) (lookup (.right node) v)))))

I this is set, should have key&value to act as map

Page 18: CPL 2016, week 11 - Clojure immutable data structures · 2016-04-25 · Institute of Computer Science, Tartu, Estonia April25,2016. Overview Lastweek I Clojurelanguagecore ... I Softwaretransactionalmemory

Immutable data structures 41/74 Binary search tree -

Insertion

(defn insert -1 [node v](if (= :leaf node)

(Node. v :leaf :leaf)(let [{nv :value nl :left nr :right} node]

(if (< v nv)(Node. nv (insert -1 nl v) nr)(Node. nv nl (insert -1 nr v))))))

15

6

3 8

33

Page 19: CPL 2016, week 11 - Clojure immutable data structures · 2016-04-25 · Institute of Computer Science, Tartu, Estonia April25,2016. Overview Lastweek I Clojurelanguagecore ... I Softwaretransactionalmemory

Immutable data structures 41/74 Binary search tree -

Insertion

(defn insert -1 [node v](if (= :leaf node)

(Node. v :leaf :leaf)(let [{nv :value nl :left nr :right} node]

(if (< v nv)(Node. nv (insert -1 nl v) nr)(Node. nv nl (insert -1 nr v))))))

15

6

3 8

7

33

Page 20: CPL 2016, week 11 - Clojure immutable data structures · 2016-04-25 · Institute of Computer Science, Tartu, Estonia April25,2016. Overview Lastweek I Clojurelanguagecore ... I Softwaretransactionalmemory

Immutable data structures 42/74 Binary search tree -

Insertion (2)

I Record may have many fields – we want to redefine oneI Record acts as a type (later) and as a dict

I use assoc as for dictionaryI record fields accessed by Keyword keys

(defn insert [node v](if (= :leaf node)

(Node. v :leaf :leaf)(if (< v (.value node))

(assoc node :left (insert (.left node) v))(assoc node :right (insert (:right node) v)))))

Page 21: CPL 2016, week 11 - Clojure immutable data structures · 2016-04-25 · Institute of Computer Science, Tartu, Estonia April25,2016. Overview Lastweek I Clojurelanguagecore ... I Softwaretransactionalmemory

Immutable data structures 43/74 Binary search tree -

Deletion (1)

(defn remove -smallest [node];; Remove the smallest value from the tree and;; return it with the node root.(when node

(let [[Yp Tp] (remove -smallest (.left node ))](if Yp

[Yp (assoc node :left Tp)][(. value node) (:right node )]))))

Y

T1 T2

?

T1 T2Yp

Yp

T1 TpYp

Page 22: CPL 2016, week 11 - Clojure immutable data structures · 2016-04-25 · Institute of Computer Science, Tartu, Estonia April25,2016. Overview Lastweek I Clojurelanguagecore ... I Softwaretransactionalmemory

Immutable data structures 44/74 Binary search tree -

Deletion (2)

1. find v in tree2. cut nv2 (smallest) from right subtree nr

3. put nv2 and nr2 into the place of node

(defn delete [{nv :value , nl :left , nr :right :as node} v](cond(nil? node) nil;; recurse into left/right subtree , reconstruct new tree(< v nv) (Node. nv (delete nl v) nr)(> v nv) (Node. nv nl (delete nr v));; found the nvalue , return it and cut the right subtree(= v nv) (let [[nv2 nr2] (remove -smallest nr)]

(if -not (nil? nv2) ; is right subtree non -empty?(Node. nv2 nl nr2)nl))

))

Page 23: CPL 2016, week 11 - Clojure immutable data structures · 2016-04-25 · Institute of Computer Science, Tartu, Estonia April25,2016. Overview Lastweek I Clojurelanguagecore ... I Softwaretransactionalmemory

Immutable data structures 45/74 Balanced BST -

Outline

Immutable data structuresBinary TreeWorking with immutable dataBinary search treeBalanced BSTOther algorithmsPersistent vector and map

Page 24: CPL 2016, week 11 - Clojure immutable data structures · 2016-04-25 · Institute of Computer Science, Tartu, Estonia April25,2016. Overview Lastweek I Clojurelanguagecore ... I Softwaretransactionalmemory

Immutable data structures 46/74 Balanced BST -

Overview

I Balanced binary search treeI binary search treeI complexities

I lookup O(log n)I insertion O(log n)I deletion O(log n)I iterate over elements O(n)

I VariantsI Red-black treeI AVL treeI others

Page 25: CPL 2016, week 11 - Clojure immutable data structures · 2016-04-25 · Institute of Computer Science, Tartu, Estonia April25,2016. Overview Lastweek I Clojurelanguagecore ... I Softwaretransactionalmemory

Immutable data structures 47/74 Balanced BST -

Red-black tree: definition

1. A node is either red or black2. Root node is black3. All leaves are black4. Both children of every red node are black5. Same number of black nodes in each path from the root to a

leaf

15

6

3 8

33

PropertyI the longest path is less than 2 times the shortest path

I hint: shortest must be all blacks

Page 26: CPL 2016, week 11 - Clojure immutable data structures · 2016-04-25 · Institute of Computer Science, Tartu, Estonia April25,2016. Overview Lastweek I Clojurelanguagecore ... I Softwaretransactionalmemory

Immutable data structures 48/74 Balanced BST -

Rotate

I left and right rotation if two nodes are redI assume changes are made in A (B)

I right rotationI if U and root of A (root of B) are both redI change the color of the root A (root of B) to blackI preserves ordering

V

U

A B

C

U

V

A

B C

right rotate

left rotate

Page 27: CPL 2016, week 11 - Clojure immutable data structures · 2016-04-25 · Institute of Computer Science, Tartu, Estonia April25,2016. Overview Lastweek I Clojurelanguagecore ... I Softwaretransactionalmemory

Immutable data structures 49/74 Balanced BST -

Rotate right: code

(defn - rotate -right -if -reds [{U :left C :right :as V}](let [A (:left U) B (:right U)]

(cond(or ; two cases when need to rotate(and (= (:color U) :red) (= (: color A) :red))(and (= (:color U) :red) (= (: color B) :red)))

(assoc U:left (assoc A :color :black):right (assoc V :left B))

:true V ; else do not rotate)))

Page 28: CPL 2016, week 11 - Clojure immutable data structures · 2016-04-25 · Institute of Computer Science, Tartu, Estonia April25,2016. Overview Lastweek I Clojurelanguagecore ... I Softwaretransactionalmemory

Immutable data structures 50/74 Balanced BST -

Rotate left: code

(defn - rotate -left -if-reds [{A :left V :right :as U}](let [B (:left V) C (:right V)]

(cond(or ; two cases when need to rotate(and (= (:color V) :red) (= (: color B) :red))(and (= (:color V) :red) (= (: color C) :red)))

(assoc V:left (assoc U :right B):right (assoc C :color :black))

:true U ; else do not rotate)))

Page 29: CPL 2016, week 11 - Clojure immutable data structures · 2016-04-25 · Institute of Computer Science, Tartu, Estonia April25,2016. Overview Lastweek I Clojurelanguagecore ... I Softwaretransactionalmemory

Immutable data structures 51/74 Balanced BST -

Insertion (1)

I insert red node as in binary search treeI rotate if somewhere appear two red nodes

I leave black in the root (may appear red as the result ofrotation)

(defn insert [v T](let [T2 (insert -and -rotate v T)]

(assoc T2 :color :black )))

Page 30: CPL 2016, week 11 - Clojure immutable data structures · 2016-04-25 · Institute of Computer Science, Tartu, Estonia April25,2016. Overview Lastweek I Clojurelanguagecore ... I Softwaretransactionalmemory

Immutable data structures 52/74 Balanced BST -

Insertion (2)

I insert here if in leaf or found the locationI otherwise, insert new value into the left or right subtree

I try to rotate right or left correspondingly

(defn - insert -and -rotate [v T](cond(nil? T) (Node. :red v nil nil)(= v (. value T)) T(< v (.value T)) (let [T2 (insert -and -rotate v (.left T))]

(rotate -right -if-reds (assoc T :left T2)))(> v (.value T)) (let [T2 (insert -and -rotate v (.right T))]

(rotate -left -if -reds (assoc T :right T2)))))

Page 31: CPL 2016, week 11 - Clojure immutable data structures · 2016-04-25 · Institute of Computer Science, Tartu, Estonia April25,2016. Overview Lastweek I Clojurelanguagecore ... I Softwaretransactionalmemory

Immutable data structures 53/74 Other algorithms -

Outline

Immutable data structuresBinary TreeWorking with immutable dataBinary search treeBalanced BSTOther algorithmsPersistent vector and map

Page 32: CPL 2016, week 11 - Clojure immutable data structures · 2016-04-25 · Institute of Computer Science, Tartu, Estonia April25,2016. Overview Lastweek I Clojurelanguagecore ... I Softwaretransactionalmemory

Immutable data structures 54/74 Other algorithms -

Queue (1)

I queue may be represented as list, e.g. 1|4|5|nilI adding or removing from head is easy and cheapI adding or removing from tail requires full list copy

I alternative: queue with 2 listsI Backward list is used to prepend elements to itI Forward list is used to take elements from itI queue = FList + reversed BListI if forward list is empty it is replaced with reversed backward list

Page 33: CPL 2016, week 11 - Clojure immutable data structures · 2016-04-25 · Institute of Computer Science, Tartu, Estonia April25,2016. Overview Lastweek I Clojurelanguagecore ... I Softwaretransactionalmemory

Immutable data structures 55/74 Other algorithms -

Queue (2)

fun {New} queue(nil nil) endfun {IsEmpty Q}

queue(FList BList) = Qin

FList==nil andthen BList==nilend% append element to the queueproc {Append Q X ?Qn}

queue(FList BList) = Qin

Qn = queue(FList X|BList)end

Page 34: CPL 2016, week 11 - Clojure immutable data structures · 2016-04-25 · Institute of Computer Science, Tartu, Estonia April25,2016. Overview Lastweek I Clojurelanguagecore ... I Softwaretransactionalmemory

Immutable data structures 56/74 Other algorithms -

Queue (3)

% take element from the queueproc {Take Q ?X ?Qn}

queue(FList BList) = Qin

if FList\=nil thenX = FList.1Qn = queue(FList.2 BList)

elseif BList\=nil then RBList in% reverseRBList = {Reverse BList}X = RBList.1Qn = queue(RBList.2 nil)

elseraise app("List is empty") end

endend

Page 35: CPL 2016, week 11 - Clojure immutable data structures · 2016-04-25 · Institute of Computer Science, Tartu, Estonia April25,2016. Overview Lastweek I Clojurelanguagecore ... I Softwaretransactionalmemory

Immutable data structures 57/74 Other algorithms -

Queue (4)

I new reference is created for the updated queue% append elementsQu = {New}Qu2 = {Append Qu 3}Qu3 = {Append Qu2 1}Qu4 = {Append Qu3 2}{System.show Qu4}% take elementXQu5 = {Take Qu4 X}{System.show X}{System.show Qu5}

I easy undoI store old references: immutable data structures make it

possible (same for trees!)

Page 36: CPL 2016, week 11 - Clojure immutable data structures · 2016-04-25 · Institute of Computer Science, Tartu, Estonia April25,2016. Overview Lastweek I Clojurelanguagecore ... I Softwaretransactionalmemory

Immutable data structures 58/74 Other algorithms -

Graphs

declarative model (as compared to non-declarative)I traversing graph is possible

I complexity (usually) multiple of log nI unless graph node ids can be stored in array

I changing graph may require copying the whole graphI because of immutable dataI node referencesI same problem for double linked list

Page 37: CPL 2016, week 11 - Clojure immutable data structures · 2016-04-25 · Institute of Computer Science, Tartu, Estonia April25,2016. Overview Lastweek I Clojurelanguagecore ... I Softwaretransactionalmemory

Immutable data structures 59/74 Persistent vector and map -

Outline

Immutable data structuresBinary TreeWorking with immutable dataBinary search treeBalanced BSTOther algorithmsPersistent vector and map

Page 38: CPL 2016, week 11 - Clojure immutable data structures · 2016-04-25 · Institute of Computer Science, Tartu, Estonia April25,2016. Overview Lastweek I Clojurelanguagecore ... I Softwaretransactionalmemory

Immutable data structures 60/74 Persistent vector and map -

Persistent vector

I http://en.wikipedia.org/wiki/TrieI see (link) Understanding Clojure’s PersistentVector

implementationI tree with 32 children, elements stored from leftmost to the

rightI 2-level may store 322 = 1024 elementsI 6-level may store 326 = 230 elements

I expands as necessary – adding to the end is cheapI tail data optimization – store tail to separate buffer until

exceeds 32 elements

Page 39: CPL 2016, week 11 - Clojure immutable data structures · 2016-04-25 · Institute of Computer Science, Tartu, Estonia April25,2016. Overview Lastweek I Clojurelanguagecore ... I Softwaretransactionalmemory

Immutable data structures 61/74 Persistent vector and map -

Persistent map

Persistent hashmapI similar ideas as in Persistent vectorI see http://blog.higher-order.net/2009/09/08/understanding-

clojures-persistenthashmap-deftwicePersistent sorted map

I implementation is immutable balanced search tree

(def m (sorted -map 1 5 2 "z")); -> #'user/m

m; -> {1 5, 2 "z"}

(m 1); -> 5

(type m); -> clojure.lang.PersistentTreeMap