immutable frontend clojurescript · WHY WE LIKE CLOJURESCRIPT Clarity & Consistency Strong core...

57
THE IMMUTABLE FRONTEND IN CLOJURESCRIPT Logan Linn (@loganlinn) QCon SF 2014 1

Transcript of immutable frontend clojurescript · WHY WE LIKE CLOJURESCRIPT Clarity & Consistency Strong core...

Page 1: immutable frontend clojurescript · WHY WE LIKE CLOJURESCRIPT Clarity & Consistency Strong core library over clean abstractions Macros Share code with rest of code-base 30 "It is

THE IMMUTABLE FRONTEND IN CLOJURESCRIPTLogan Linn (@loganlinn) QCon SF 2014

1

Page 2: immutable frontend clojurescript · WHY WE LIKE CLOJURESCRIPT Clarity & Consistency Strong core library over clean abstractions Macros Share code with rest of code-base 30 "It is

PRISMATIC

Personalized, interest-based newsfeeds

Crawlers, Machine Learning, Clients

We’re very functional

99.9% Clojure backend

ClojureScript frontend

We <3 open-source2

Page 3: immutable frontend clojurescript · WHY WE LIKE CLOJURESCRIPT Clarity & Consistency Strong core library over clean abstractions Macros Share code with rest of code-base 30 "It is

3

Page 4: immutable frontend clojurescript · WHY WE LIKE CLOJURESCRIPT Clarity & Consistency Strong core library over clean abstractions Macros Share code with rest of code-base 30 "It is

IMMUTABLE FRONTEND

ClojureScript gives us immutability and more

Immutability simplifies data-flow

React allows us to render predictably with pure functions

4

Page 5: immutable frontend clojurescript · WHY WE LIKE CLOJURESCRIPT Clarity & Consistency Strong core library over clean abstractions Macros Share code with rest of code-base 30 "It is

IMMUTABLE FRONTEND

5

ReactApp State

User Events

APIData

ComponentTree

DOM

Page 6: immutable frontend clojurescript · WHY WE LIKE CLOJURESCRIPT Clarity & Consistency Strong core library over clean abstractions Macros Share code with rest of code-base 30 "It is

OUTLINE

Challenges of a Building a Frontend

Immutability

ClojureScript

An Immutable Frontend

6

Page 7: immutable frontend clojurescript · WHY WE LIKE CLOJURESCRIPT Clarity & Consistency Strong core library over clean abstractions Macros Share code with rest of code-base 30 "It is

CHALLENGES OF BUILDING A FRONTEND

Interactive UIs have a human factor

Asynchronous programming

Complexity comes from every angle

Software complexity is a compounding debt

7

Page 8: immutable frontend clojurescript · WHY WE LIKE CLOJURESCRIPT Clarity & Consistency Strong core library over clean abstractions Macros Share code with rest of code-base 30 "It is

INCIDENTAL COMPLEXITY

Managing state

8

Page 9: immutable frontend clojurescript · WHY WE LIKE CLOJURESCRIPT Clarity & Consistency Strong core library over clean abstractions Macros Share code with rest of code-base 30 "It is

INCIDENTAL COMPLEXITY

Managing state

Mutating data

9

Page 10: immutable frontend clojurescript · WHY WE LIKE CLOJURESCRIPT Clarity & Consistency Strong core library over clean abstractions Macros Share code with rest of code-base 30 "It is

MODEL-VIEW-*

Domain vs Presentational data

Keeping data and DOM in sync

MVC, MVP, MVVM, etc.

10

animate

Page 11: immutable frontend clojurescript · WHY WE LIKE CLOJURESCRIPT Clarity & Consistency Strong core library over clean abstractions Macros Share code with rest of code-base 30 "It is

EVENTS AND DATA-BINDING

Most frameworks today structured around Models

Models publish changes via global events

Views subscribe to changes and update

Data bindings let you be declarative

11

Page 12: immutable frontend clojurescript · WHY WE LIKE CLOJURESCRIPT Clarity & Consistency Strong core library over clean abstractions Macros Share code with rest of code-base 30 "It is

ControllerModel View

12

Page 13: immutable frontend clojurescript · WHY WE LIKE CLOJURESCRIPT Clarity & Consistency Strong core library over clean abstractions Macros Share code with rest of code-base 30 "It is

EVENT AND DATA-BINDING

Encourages mutation

Data-flow becomes opaque, potentially hazardous

Makes it easier, but not simpler

13

Page 14: immutable frontend clojurescript · WHY WE LIKE CLOJURESCRIPT Clarity & Consistency Strong core library over clean abstractions Macros Share code with rest of code-base 30 "It is

MVC DATA-FLOW

14

Page 15: immutable frontend clojurescript · WHY WE LIKE CLOJURESCRIPT Clarity & Consistency Strong core library over clean abstractions Macros Share code with rest of code-base 30 "It is

MVC DATA-FLOW

15

ControllerModel View

Page 16: immutable frontend clojurescript · WHY WE LIKE CLOJURESCRIPT Clarity & Consistency Strong core library over clean abstractions Macros Share code with rest of code-base 30 "It is

MVC DATA-FLOW

16

ControllerModel View

DOM

User Events

Page 17: immutable frontend clojurescript · WHY WE LIKE CLOJURESCRIPT Clarity & Consistency Strong core library over clean abstractions Macros Share code with rest of code-base 30 "It is

What if we prioritized a simple data-flow?

17

Page 18: immutable frontend clojurescript · WHY WE LIKE CLOJURESCRIPT Clarity & Consistency Strong core library over clean abstractions Macros Share code with rest of code-base 30 "It is

SINGLE-DIRECTION DATA FLOW

PureRender

18

DOMApp State

User Events

Page 19: immutable frontend clojurescript · WHY WE LIKE CLOJURESCRIPT Clarity & Consistency Strong core library over clean abstractions Macros Share code with rest of code-base 30 "It is

IMMUTABILITY

19

Page 20: immutable frontend clojurescript · WHY WE LIKE CLOJURESCRIPT Clarity & Consistency Strong core library over clean abstractions Macros Share code with rest of code-base 30 "It is

A MUTABLE WORLD

20

x = Domain.List.from([‘x'])y = x.unshift('y')z = x.unshift('z')

print(z.second()) // 'x' or 'y'?print(x) // ['x'] or ['z', 'y', 'x']?

Page 21: immutable frontend clojurescript · WHY WE LIKE CLOJURESCRIPT Clarity & Consistency Strong core library over clean abstractions Macros Share code with rest of code-base 30 "It is

AN IMMUTABLE WORLD…

21

x = Domain.List.from([‘x'])y = x.unshift('y')z = x.unshift('z')

print(z.second()) // 'x', final answer!print(x) // ['x'], fasho!

Page 22: immutable frontend clojurescript · WHY WE LIKE CLOJURESCRIPT Clarity & Consistency Strong core library over clean abstractions Macros Share code with rest of code-base 30 "It is

RENDERING WITH PURE FUNCTIONS

22

ƒ(S1) = D1ƒ(S2) = D2ƒ(S1) = D1

t

Page 23: immutable frontend clojurescript · WHY WE LIKE CLOJURESCRIPT Clarity & Consistency Strong core library over clean abstractions Macros Share code with rest of code-base 30 "It is

IMMUTABILITY ON THE FRONTEND

Simplicity & Clarity

23

Page 24: immutable frontend clojurescript · WHY WE LIKE CLOJURESCRIPT Clarity & Consistency Strong core library over clean abstractions Macros Share code with rest of code-base 30 "It is

IMMUTABILITY ON THE FRONTEND

Simplicity & Clarity

Predictability

24

Page 25: immutable frontend clojurescript · WHY WE LIKE CLOJURESCRIPT Clarity & Consistency Strong core library over clean abstractions Macros Share code with rest of code-base 30 "It is

IMMUTABILITY ON THE FRONTEND

Simplicity & Clarity

Predictability

Less defensive programming, i.e. _.cloneDeep(obj)

25

Page 26: immutable frontend clojurescript · WHY WE LIKE CLOJURESCRIPT Clarity & Consistency Strong core library over clean abstractions Macros Share code with rest of code-base 30 "It is

IMMUTABILITY ON THE FRONTEND

Simplicity & Clarity

Predictability

Less defensive programming, i.e. _.cloneDeep(obj)

Constant time dirty checking

26

Page 27: immutable frontend clojurescript · WHY WE LIKE CLOJURESCRIPT Clarity & Consistency Strong core library over clean abstractions Macros Share code with rest of code-base 30 "It is

IMMUTABILITY & PERFORMANCE

Persistent data structures

Structural sharing

Memory efficiency

Conjoin to collection in O(1)

Update hash-map in O(log32 n) vs O(n)

27

ab

c

Page 28: immutable frontend clojurescript · WHY WE LIKE CLOJURESCRIPT Clarity & Consistency Strong core library over clean abstractions Macros Share code with rest of code-base 30 "It is

CLOJURE(SCRIPT)

28

Page 29: immutable frontend clojurescript · WHY WE LIKE CLOJURESCRIPT Clarity & Consistency Strong core library over clean abstractions Macros Share code with rest of code-base 30 "It is

CLOJURE & CLOJURESCRIPT

Dynamic, Functional, Lisp

Clojure

Compiles to JVM bytecode

7 years old

ClojureScript

Compiles to JavaScript

3 years old29

Page 30: immutable frontend clojurescript · WHY WE LIKE CLOJURESCRIPT Clarity & Consistency Strong core library over clean abstractions Macros Share code with rest of code-base 30 "It is

WHY WE LIKE CLOJURESCRIPT

Clarity & Consistency

Strong core library over clean abstractions

Macros

Share code with rest of code-base

30

"It is better to have 100 functions operate on one

data structure than 10 functions on 10 data

structures." —Alan Perlis, 1982

Page 31: immutable frontend clojurescript · WHY WE LIKE CLOJURESCRIPT Clarity & Consistency Strong core library over clean abstractions Macros Share code with rest of code-base 30 "It is

MUTATION REQUIRES OPT-IN

Immutable data by default

State modeled with reference to immutable value

Special functions to mutate reference & dereference value

Easy to identify side-effects

31

Page 32: immutable frontend clojurescript · WHY WE LIKE CLOJURESCRIPT Clarity & Consistency Strong core library over clean abstractions Macros Share code with rest of code-base 30 "It is

(def state-ref (atom {}))

(deref state-ref) ;; => {}

(reset! state-ref {:a 1})@state-ref ;; => {:a 1}

(defn increment-a [state] (update-in state [:a] inc))

(increment-a @state-ref) ;; => {:a 2}@state-ref ;; => {:a 1}

(swap! state-ref increment-a)@state-ref ;; => {:a 2}

32

Page 33: immutable frontend clojurescript · WHY WE LIKE CLOJURESCRIPT Clarity & Consistency Strong core library over clean abstractions Macros Share code with rest of code-base 30 "It is

SEPARATION OF CONCERNS

Time

Relative moments when events occur

State

A value at a point in time

Identity

Entity associated with state over time33

Page 34: immutable frontend clojurescript · WHY WE LIKE CLOJURESCRIPT Clarity & Consistency Strong core library over clean abstractions Macros Share code with rest of code-base 30 "It is

AN IMMUTABLE ARCHITECTURE

34

Page 35: immutable frontend clojurescript · WHY WE LIKE CLOJURESCRIPT Clarity & Consistency Strong core library over clean abstractions Macros Share code with rest of code-base 30 "It is

AN IMMUTABLE ARCHITECTURE

35

ReactApp State

User Events

HTTPData

ComponentTree

DOM

Page 36: immutable frontend clojurescript · WHY WE LIKE CLOJURESCRIPT Clarity & Consistency Strong core library over clean abstractions Macros Share code with rest of code-base 30 "It is

AN IMMUTABLE ARCHITECTURE

state

36

Page 37: immutable frontend clojurescript · WHY WE LIKE CLOJURESCRIPT Clarity & Consistency Strong core library over clean abstractions Macros Share code with rest of code-base 30 "It is

AN IMMUTABLE ARCHITECTURE

component

component

component

state

component

37

Page 38: immutable frontend clojurescript · WHY WE LIKE CLOJURESCRIPT Clarity & Consistency Strong core library over clean abstractions Macros Share code with rest of code-base 30 "It is

AN IMMUTABLE ARCHITECTURE

state

component

component component

component

38

Page 39: immutable frontend clojurescript · WHY WE LIKE CLOJURESCRIPT Clarity & Consistency Strong core library over clean abstractions Macros Share code with rest of code-base 30 "It is

AN IMMUTABLE ARCHITECTURE

state

component component

component

component

39

Page 40: immutable frontend clojurescript · WHY WE LIKE CLOJURESCRIPT Clarity & Consistency Strong core library over clean abstractions Macros Share code with rest of code-base 30 "It is

AN IMMUTABLE ARCHITECTURE

state

component component

40

Page 41: immutable frontend clojurescript · WHY WE LIKE CLOJURESCRIPT Clarity & Consistency Strong core library over clean abstractions Macros Share code with rest of code-base 30 "It is

AN IMMUTABLE ARCHITECTURE

state

component

41

Page 42: immutable frontend clojurescript · WHY WE LIKE CLOJURESCRIPT Clarity & Consistency Strong core library over clean abstractions Macros Share code with rest of code-base 30 "It is

AN IMMUTABLE ARCHITECTURE

state

component

42

component tree

Page 43: immutable frontend clojurescript · WHY WE LIKE CLOJURESCRIPT Clarity & Consistency Strong core library over clean abstractions Macros Share code with rest of code-base 30 "It is

actions

AN IMMUTABLE ARCHITECTURE

43

state

component tree

Page 44: immutable frontend clojurescript · WHY WE LIKE CLOJURESCRIPT Clarity & Consistency Strong core library over clean abstractions Macros Share code with rest of code-base 30 "It is

AN IMMUTABLE ARCHITECTURE

44

state

component tree

Page 45: immutable frontend clojurescript · WHY WE LIKE CLOJURESCRIPT Clarity & Consistency Strong core library over clean abstractions Macros Share code with rest of code-base 30 "It is

AN IMMUTABLE ARCHITECTURE

45

component tree

Page 46: immutable frontend clojurescript · WHY WE LIKE CLOJURESCRIPT Clarity & Consistency Strong core library over clean abstractions Macros Share code with rest of code-base 30 "It is

AN IMMUTABLE ARCHITECTURE

46

S1

component tree

S2

Page 47: immutable frontend clojurescript · WHY WE LIKE CLOJURESCRIPT Clarity & Consistency Strong core library over clean abstractions Macros Share code with rest of code-base 30 "It is

AN IMMUTABLE ARCHITECTURE

47

ReactApp State

User Events

HTTPData

ComponentTree

DOM

Page 48: immutable frontend clojurescript · WHY WE LIKE CLOJURESCRIPT Clarity & Consistency Strong core library over clean abstractions Macros Share code with rest of code-base 30 "It is

AN IMMUTABLE ARCHITECTURE

Immutable application state

Business logic written as pure functions

Declarative rendering

48

Page 49: immutable frontend clojurescript · WHY WE LIKE CLOJURESCRIPT Clarity & Consistency Strong core library over clean abstractions Macros Share code with rest of code-base 30 "It is

APP STATE

Reference to an immutable value

Updating state changes reference

Business logic as pure functions

Compose multiple operations & apply at once

49

App State

Page 50: immutable frontend clojurescript · WHY WE LIKE CLOJURESCRIPT Clarity & Consistency Strong core library over clean abstractions Macros Share code with rest of code-base 30 "It is

REACT

UI rendering library from Facebook

“Not templating. Not MVC. It’s like a declarative jQuery” -Pete Hunt

Manipulates DOM & handles events (thats all)

Trending, and rightfully so!

50

ReactDOM

Page 51: immutable frontend clojurescript · WHY WE LIKE CLOJURESCRIPT Clarity & Consistency Strong core library over clean abstractions Macros Share code with rest of code-base 30 "It is

REACT

var HelloMessage = React.createClass({ render: function() { return DOM.div({}, "Hello " + this.props.name); }});

React.render(HelloMessage({name: "QCon"}), mountNode);React.render(HelloMessage({name: "QCon SF"}), mountNode);

51

Page 52: immutable frontend clojurescript · WHY WE LIKE CLOJURESCRIPT Clarity & Consistency Strong core library over clean abstractions Macros Share code with rest of code-base 30 "It is

REACT

Basic building block is a component with render() method

Data in, “virtual DOM” out

When data changes, render() is re-run

Performs diff between vDOM and actual DOM

Pushes out minimal set of changes to keep in sync

52

ReactDOM

Page 53: immutable frontend clojurescript · WHY WE LIKE CLOJURESCRIPT Clarity & Consistency Strong core library over clean abstractions Macros Share code with rest of code-base 30 "It is

REACT & CLOJURESCRIPT

Shared design principles

pure and composable functions

simplicity through predictability

Actually useful API

Easy to compose from ClojureScript

Libraries like Om, Reagent, Quiescent53

Page 54: immutable frontend clojurescript · WHY WE LIKE CLOJURESCRIPT Clarity & Consistency Strong core library over clean abstractions Macros Share code with rest of code-base 30 "It is

DOM2

REACT & CLOJURESCRIPT

54

S1

D1

S2

D2

React

DOM1

Page 55: immutable frontend clojurescript · WHY WE LIKE CLOJURESCRIPT Clarity & Consistency Strong core library over clean abstractions Macros Share code with rest of code-base 30 "It is

SIMPLE OM EXAMPLE

55

Page 56: immutable frontend clojurescript · WHY WE LIKE CLOJURESCRIPT Clarity & Consistency Strong core library over clean abstractions Macros Share code with rest of code-base 30 "It is

WRAP-UP

Immutability & referential transparency have many benefits

Testing & Reasoning

Application architecture

Invest in languages & tools that prioritize simplicity

Clojure & ClojureScript are great!

React is great!56

Page 57: immutable frontend clojurescript · WHY WE LIKE CLOJURESCRIPT Clarity & Consistency Strong core library over clean abstractions Macros Share code with rest of code-base 30 "It is

THANKS!@loganlinn @prismatic

57