ClojureScript - A functional Lisp for the browser

18
ClojureScript A functional Lisp for the browser @friemens

Transcript of ClojureScript - A functional Lisp for the browser

Page 1: ClojureScript - A functional Lisp for the browser

ClojureScript

A functional Lisp for the browser

@friemens

Page 2: ClojureScript - A functional Lisp for the browser
Page 3: ClojureScript - A functional Lisp for the browser

Oh, what an alien look!

Page 4: ClojureScript - A functional Lisp for the browser

Lispy syntax

Ordered

Associative

Function

Invocation

var x = [1,2,3];(def x [1 2 3])

(def m {:a “Foo“}) var m = {a: “Foo“};

function bar (a) { return a + 42;}

(defn bar [a] (+ a 42))

bar(0);(bar 0)

Page 5: ClojureScript - A functional Lisp for the browser

Interactive Development Demohttps://github.com/friemen/zackzack

Page 6: ClojureScript - A functional Lisp for the browser

Thou shalt not mutate in place

Page 7: ClojureScript - A functional Lisp for the browser

Mutability causes cognitive load

var x = [1,2,3];foo(x);

After foo,what's in x?

Page 8: ClojureScript - A functional Lisp for the browser

ClojureScript is built on immutability

(def x [1 2 3])(foo x)(assert (= x [1 2 3]))

Page 9: ClojureScript - A functional Lisp for the browser

… on efficient immutability

Structuralsharing

x x'

Page 10: ClojureScript - A functional Lisp for the browser

Om on top of React

Page 11: ClojureScript - A functional Lisp for the browser

Databinding

Appstate

DOM

event

updates

mutations

Controller

e.g. Angular

transform

renderdiff + merge

DOM

Appstate

swap

React+Om

Shadow DOM

event

DOM operations are soooo sloooow.

Page 12: ClojureScript - A functional Lisp for the browser

Burn Hollywood Burn!*

Public Enemy (1990)*

Page 13: ClojureScript - A functional Lisp for the browser

Callbacks are ok, but, uhm ...

function reloadAddressbook (state, event) {

ask("Are you sure?", function (answer) {

if (answer) {

ajax.get("/addresses", function (response) {

if (response.statusCode == 200) {

state.addresses.items = response.body; } }); } });}

Ask for confirmation

ok?

Issue GET request

success?

Replace items

But how do you implement concurrent requests?

Page 14: ClojureScript - A functional Lisp for the browser

CSP* with core.async = channels + go blocks

Communicating Sequential Processes, Tony Hoare (1978)*

(def c1 (chan))

(go-loop [xs []] (let [x (<! c1)] (println "Got" x ", xs so far:" xs) (recur (conj xs x))))

(put! c1 "foo");; outputs: Got bar , xs so far: [foo]

a blocking read

make a new channelcreates a lightweight

process

async write

Page 15: ClojureScript - A functional Lisp for the browser

core.async: no need for callbacks

Ask for confirmation

ok?

Issue GET request

success?

Replace items

(defn <addressbook-reload [state event]

(go (if (= :ok (<! (<ask "Are you sure?")))

(let [{s :status addresses :body} (<! (http/get "/addresses"))]

(if (= 200 s)

(assoc-in state [:addresses :items] addresses) state)))

Page 16: ClojureScript - A functional Lisp for the browser

Wrap up

Page 17: ClojureScript - A functional Lisp for the browser

ClojureScript is ...

... overkill for little enhancements

… a mature language to tackle UI complexity

… demanding to learn, but this will pay-off

Page 18: ClojureScript - A functional Lisp for the browser

Thank you for listening!

Questions?

@friemens www.itemis.de