CPL 2016, week 12 Clojure large scale design Oleg Batrashev Institute of Computer Science, Tartu, Estonia April 25, 2016
Overview Last weeks ◮ Clojure language core ◮ Immutable data structures This week ◮ Clojure simple state and design Next weeks ◮ Software transactional memory ◮ Agents in Clojure
Mutable state 56/68 - State, identity and time From “The Joy of Clojure” book ◮ Time —The relative moments when events occur ◮ State —A snapshot of an entity’s properties at a moment in time ◮ Identity —The logical entity identified by a common stream of states occurring over time
Mutable state 57/68 - Clojure’s state and identity ◮ state is often seen as a snapshot of object properties at a given moment ◮ immutable by definition ◮ identity can have different states in time ◮ sarah = new Person(Sarah, 25) ◮ sarah variable is the identity and object value is her state? ◮ but this state is mutable ◮ Clojure tries to distinguish an identity and its immutable states ◮ preserves historical states of identity ◮ identity is one of Clojure reference types
Mutable state 58/68 - Clojure’s reference types ◮ Refs manage coordinated, synchronous changes to shared state. ◮ Atoms manage uncoordinated, synchronous changes to shared state. ◮ Agents manage asynchronous changes to shared state. ◮ Vars manage thread-local state.
Mutable state 59/68 - Vars ◮ def / defn create global variable ◮ by default changable by everyone, no garantees ◮ allows to create thread-local state (def ^:dynamic foo 41)(binding [foo 42] (println foo))(println foo) ◮ get the “var” object itself (var foo) ; -> #'user/foo ◮ user is namespace name ◮ used to store global(namespace)/thread local configuration and functions ◮ for application data prefer atoms, refs, and agents!
Mutable state 60/68 - Atoms ◮ (atom initialState) ◮ deref/@ – read value of an atom ◮ reset! – set the value of an atom ◮ swap! – atomically modify the value by using function, may be re-executed in case of conflict (def a (atom 34)) (swap! a (fn [state] (inc state ))) ; -> 35 (println @a) ; -> 35
Program structure 61/68 - Namespaces ◮ ns – specify namespace ◮ allows to inline the following commands ◮ require – loads namespace into memory, defining its types, etc ◮ refer – imports names from namespace into local scope ◮ use = require + refer (ns suffixtree ) (require '[clojure.pprint :refer [pprint ]]) ◮ import – for Java classes (import '(java.io FileInputStream InputStreamReader ))
Program structure 62/68 - Types and protocols ◮ a way to do “object oriented” programming in Clojure ◮ type/record – collection of data (defrecord Person [name x y]) ◮ records are immutable but allow dictionary-like manipulations ◮ types allow mutable fields that are private ◮ both can implement some protocols ◮ protocol – functional interface to types/records ( defprotocol Movable (move [this direc] "Move someone .") (jump [this direc distance ])) ◮ first parameter is special – used for method dispatch ◮ use multimethods for multiparameter dispatch
Program structure 63/68 - Extend types One type with several protocols (extend -type AType AProtocol (method -from -AProtocol [this x] ( ;... implementation for AType )) AnotherProtocol (method1 -from - AnotherProtocol [this x] ( ;... implementation for AType )) (method2 -from - AnotherProtocol [this x y] ( ;... implementation for AType ))) ◮ possible to do inline in deftype
Program structure 64/68 - Extend protocols One protocol for multiple types (extend -protocol AProtocol AType (method1 -from -AProtocol [this x] ( ;... implementation for AType )) AnotherType (method1 -from -AProtocol [this x] ( ;... implementation for AnotherType )) (method2 -from -AProtocol [this x y] ( ;... implementation for AnotherType ))) ◮ possible to do inline in defprotocol ◮ extend command for reuse of methods
Program structure 65/68 - Multidispatch: defmethod (defrecord Node [value left right ]) (defmethod print -method Node [node wr] (print -simple (str "<" (. value node) " " "l=" (print -str (. left node )) " " "r=" (print -str (. right node )) ">") wr))
Program structure 66/68 - Java interop ◮ proxy – anonymous class with immediate instance ◮ gen-class – full-featured class extension
Program structure 67/68 - Summary
Recommend
More recommend