Slide 1

Slide 1 text

Clojure! An Introduction! with bits of Domain-Driven Design and Functional Databases...! ! Java User Group Lausanne – Oct 2013!

Slide 2

Slide 2 text

#whoami   Jérémie Grodziski Software Designer and Programmer @jgrodziski [email protected] blog.zenmodeler.com   www.redsen.fr/blog  

Slide 3

Slide 3 text

Clojure is... Functional Dynamic a dialect of LISP Homoiconic (a.k.a. Code is Data, Data is Code) Immutable by default using Runtime Polymorphism Concurrent Hosted on the JVM

Slide 4

Slide 4 text

Essential Functional Programming Concepts First-Class , Pure and Higher- Order Function Immutability Recursion Lazyness

Slide 5

Slide 5 text

First-class Function Composable: – can be created on demand, – stored in a data structure, – passed as an argument to a function, – returned as the value of a function

Slide 6

Slide 6 text

Higher Order Function Takes one or more functions as arguments: map, reduce, filter, ... Returns a function as a result: partial, comp, ...

Slide 7

Slide 7 text

Pure Function Always return the same results given the same arguments Doesn’t cause any observable side-effects Allows referential transparency as time does not affect the result of a function invocation (function is transparent to time) Allows memoization, algebraic manipulation and increase testability

Slide 8

Slide 8 text

Function

Slide 9

Slide 9 text

Function Arguments Body Return the last expression Function invocation Anonymous function declaration = Lambda Result bound to symbol Invocation’s Arguments

Slide 10

Slide 10 text

Function Arguments Body Return the last expression Function invocation Named function declaration Result bound to symbol Invocation’s Arguments

Slide 11

Slide 11 text

Binding « Binding » = assigning a value to a symbol in a scope In Clojure, everything is an expression and return a value NO VARIABLE and NO STATEMENT ! But provide Software Transactional Memory for shared « variable »

Slide 12

Slide 12 text

The « let » special form Can be thought of as saying: « Let symbol sum have the value of expression (reduce + numbers) and symbol nb-of-items have the value of expression (count numbers) in body (/ sum nb-of-items) »

Slide 13

Slide 13 text

Function bound to symbol Anonymous Function Function bound to symbol « average » Shortcut for declaring a function bound to symbol « average »

Slide 14

Slide 14 text

Immutability All of the possible properties of immutable objects are defined at the time of their construction and can’t be changed thereafter How to get something done if things can’t change ? Use recursion instead of mutation with persistent data structure that allows structural sharing

Slide 15

Slide 15 text

Recursion Mundane recursion Use an accumulator Recur to the rescue but only in tail position and for self recursion

Slide 16

Slide 16 text

Lazyness Realize the result of an expression when it is really needed != eager (eager = statement or arguments to function are immediately evaluated) Java && (logical and) has lazy evaluation Clojure’s sequence are lazy, allows infinite sequence

Slide 17

Slide 17 text

Some scalars String Boolean Numbers Keyword Symbol

Slide 18

Slide 18 text

A few Data Structures... List Vector Map Set

Slide 19

Slide 19 text

...and a lot of Functions Alan J. Perlis, developed Algol language, 1st recipient of the Turing Award For other « Perlism »:http://www.cs.yale.edu/quotes.html « It is better to have 100 functions operate on 1 data structure than 10 functions on 10 data structures »

Slide 20

Slide 20 text

A lot of built-in Functions Etc. Excerpt from clojure.org/cheatsheet

Slide 21

Slide 21 text

Persistent Data Structure When a persistent data structure is "modified," the data is not mutated. Rather, a new immutable version of the data structure is returned Structural sharing is the technique used to make Clojure's persistent data structures efficient Structural sharing relies on the data's immutability to make sharing possible between the old and new instances of the data

Slide 22

Slide 22 text

Clojure Philosophy or « In the brain of Rich Hickey » Simplicity, freedom to focus, empowerment, consistency, and clarity Value Driven Programming or Facts-Oriented Programming instead of Place-Oriented Programming Libraries not Frameworks

Slide 23

Slide 23 text

Dynamic A Clojure program is not just something you compile and run, but something with which you can interact ⇒ REPL Oriented Programming Anything you enter into the REPL or load using load-file is automatically compiled to JVM bytecode on the fly

Slide 24

Slide 24 text

REPL Oriented Programming Read Eval Print Loop A REPL is a mean for interactive development

Slide 25

Slide 25 text

Clojure is a Lisp dialect Lambda calculus yields an extremely small core Almost no syntax Core advantage still code-as-data and syntactic abstraction What about the standard Lisps (Common Lisp and Scheme)? –  Slow/no innovation post standardization –  Core data structures mutable, not extensible –  No concurrency in specs –  Good implementations already exist for JVM (ABCL, Kawa, SISC et al) –  Standard Lisps are their own platforms Clojure is a Lisp not constrained by backwards compatibility –  Extends the code-as-data paradigm to maps and vectors –  Defaults to immutability –  Core data structures are extensible abstractions –  Embraces a platform (JVM) excerpt from clojure.org/rationale

Slide 26

Slide 26 text

A dialect of LISP: everything is an expression In clojure, everything is an expression that return a value, there are no statements, hence the term « value-based programming ». Clojure: returns true or false (so can be evaluated) Java: returns nothing but can change state

Slide 27

Slide 27 text

A dialect of LISP: Homoiconicity All Code in Clojure are list in the form It enables very powerful meta-programming (quote exp) and (eval exp) « Code is Data, Data is Code » from homo - the same - and icon - representation -

Slide 28

Slide 28 text

Code is Data Vector List Symbols List

Slide 29

Slide 29 text

Macros Code that produce code quote ` unquote ~ unquote-splicing ~@

Slide 30

Slide 30 text

Concurrency Tranparent: pmap, reducers Software Transactional Memory Atoms, Ref, Actors = Agents Core.async (channel and go routine) Coordinated Independant Synchronous Refs Atoms Asynchronous Agents

Slide 31

Slide 31 text

Java Interoperability Java Clojure Calling Java from Clojure Calling Clojure from Java With RT: With gen-class:

Slide 32

Slide 32 text

Temporal aspect of State management and Identity Identity Single Married Adult Minor Time Adult state Marital state Divorced •  Business Id : 12345678 •  John •  Doe •  5 November 1976 in Paris •  … Entity State Entity Object at a given moment in time Identity State

Slide 33

Slide 33 text

State, Identity and Function State Identity State 1 State 2 State 3 Function Function Event triggers Event triggers •  value 1a •  value 1b •  value 1c •  value 1a •  value 1b •  value 1c •  value 2a •  value 2b •  value 1a •  value 1b •  value 1c •  value 2a •  value 2b •  value 3a Publish Internal Event Publish Internal Event ... Time

Slide 34

Slide 34 text

Example with Order entity Identity : Order N° 123456 Submitted Paid Shipped pay ship Payment details from Payment Gateway received Carrier data q  Customer Data q  Product Lines (product + qty) q  Shipping Data States submit q  Customer Data q  Product Lines (product + qty) q  Shipping Data q  Payment Data q  Customer Data q  Product Lines (product + qty) q  Shipping Data q  Payment Data q  Carrier Data Front website form submitted Order submitted event Order paid event Order shipped event Time

Slide 35

Slide 35 text

OOP done right with Clojure Identity State as values Function Method = function applied to an identity’s state, [eventually producing a new state] Entity = Identity + State Protocol = Interface = set of methods

Slide 36

Slide 36 text

Clojure Ecosystem: Debugging Spyscope clojure/tools.trace nREPL Ritz, nREPL with a debugger

Slide 37

Slide 37 text

Clojure Ecosystem: Testing clojure.test: (deftest),(with-test), (run-test) Test stored in function’s meta at :test Mocking: (with-redefs), built-in! Midje: facts

Slide 38

Slide 38 text

Clojure Ecosystem: Build Leiningen Like Maven mais en mieux ! J

Slide 39

Slide 39 text

Clojure Ecosystem: Web Request and Response plumbing (HTTP) – Ring Routing Request to a Handler (function) – Compojure Templating the response from the handler – Hiccup and Enlive

Slide 40

Slide 40 text

Clojure Ecosystem: Database •  Drivers to all databases •  Datomic

Slide 41

Slide 41 text

Datomic Datomic is a database of flexible, time- based facts, supporting queries and joins, with elastic scalability, and ACID transactions We’ll cover Datomic Data Model, Architecture and Programming Model

Slide 42

Slide 42 text

Datomic Data Model Immutable Data –  Data consisting of immutable values. How? facts don’t change when you incorporate time in the data. Time in data allows the past to be retained (or not), and supports point-in-time queries. 'latest' view in traditional database vs retaining all changes. Datomic is a database of facts, not places. Atomic Data - the Datom –  Facts are recorded as independent atoms of information. Datomic calls such atomic facts 'datoms'. A datom consists of an entity, attribute, value and transaction (time). Minimal Schema –  All databases have a schema, whether they are written down or not. The schema required to encode datoms consisting primarily of the attribute definitions, which specify name, type, cardinality etc. The Database –  A Datomic database is just a set of datoms, indexed in various ways. These indexes contain all of the data, not pointers to data (i.e. they are covering indexes). The storage service and caches are just a distribution network for the data segments of these indexes, all of which are immutable, and thus effectively and coherently cached.

Slide 43

Slide 43 text

Datomic breaks traditional DB services apart Peers: The peer component is a library that gets embedded in the applications –  Submits transactions to, and accepts changes from, the transactor –  Includes all communication components for talking to transactors and storage services –  Provides data access, caching, and query capability to the application, reading from the storage service as needed Transactors –  Accept transactions –  Process them serially –  Commit the results to the storage service –  all writes are synchronously made to redundant storage –  Transmit changes to the peers –  Index in the background, place indexes in storage service Storage services –  Provide an interface to highly reliable, redundant storage –  Available from third-parties: Amazon DynamoDB, RDBMS, Infinispan

Slide 44

Slide 44 text

Benefits of Datomic Architecture Separating reads and writes –  When reads are separated from writes, writes are never held up by queries. In the Datomic architecture, the transactor is dedicated to transactions, and need not service reads at all! Integrated data distribution –  Each peer and transactor manages its own local cache of data segments, in memory. This cache self-tunes to the working set of that application. Every peer gets its own brain (query engine and cache) –  Traditional client-server databases leads to impedance mismatch. The problem, though, isn't that databases are insufficiently object-oriented, rather, that applications are insufficiently declarative. Moving a proper, index-supported, declarative query engine into applications will enable them to work with data at a higher level than ever before, and at application-memory speeds. Elasticity –  Application servers are frequently scaled up and down as demand fluctuates, but traditional databases, even with read-replication configured, have difficulty scaling query capability similarly. Putting query engines in peers makes query capability as elastic as the applications themselves. In addition, putting query engines into the applications themselves means they never wait on each other's queries. Ready for the cloud –  All components are designed to run on commodity servers, with expectations that they, and their attached storage, are ephemeral. The speed of memory –  While the (disk-backed) storage service constitutes the data of record, the rest of the system operates primarily in memory.

Slide 45

Slide 45 text

DDD in Clojure •  DDD is about introducing the domain language into the source code •  Clojure’s idiom is about (very) short name –  Ex: def instead of define, inc instead of increment, etc. –  That’s not oriented towards understandability but conciseness •  Weak typing means a different way of looking after the domain language –  Symbols instead of type’s name •  The fundamentals of the language are indeed very DDD oriented –  Everything returns a Value –  Identity, State and Functions does not complects in Entity

Slide 46

Slide 46 text

Resources: Books •  Joy of Clojure •  Understanding Computation •  SICP

Slide 47

Slide 47 text

Resources: blogs, personality, newsletter •  Fogus, rich, chris houser, stuart halloway, etc.