Top Banner
Webapps with Clojure & ClojureScript @friemens
33

Clojure+ClojureScript Webapps

Jan 10, 2017

Download

Technology

Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Clojure+ClojureScript Webapps

Webapps withClojure & ClojureScript

@friemens

Page 2: Clojure+ClojureScript Webapps
Page 3: Clojure+ClojureScript Webapps

Dear audience,a word of caution:

Page 4: Clojure+ClojureScript Webapps

((((λ))))

Page 5: Clojure+ClojureScript Webapps

Language & ToolingDemos of Webapps

Frontend ArchitectureRemoting

Backend Architecture

Overview

Page 6: Clojure+ClojureScript Webapps

Language & ToolingDemos of Webapps

Frontend ArchitectureRemoting

Backend Architecture

Overview

Page 7: Clojure+ClojureScript Webapps

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 8: Clojure+ClojureScript Webapps

Cross-Plattform Coding

#?(:clj (Clojure expression) :cljs (ClojureScript expression) :cljr (Clojure CLR expression))

(defn str->int [s] #?(:clj (java.lang.Integer/parseInt s) :cljs (js/parseInt s)))

Example

Reader Conditionals

Page 9: Clojure+ClojureScript Webapps

Why is Clojure a Lisp-style language?

Lisp!

Other Languages

Time

Expressive Power

Page 10: Clojure+ClojureScript Webapps

Cross-Plattform Coding

#?(:clj (Clojure expression) :cljs (ClojureScript expression) :cljr (Clojure CLR expression))

(defn str->int [s] #?(:clj (java.lang.Integer/parseInt s) :cljs (js/parseInt s)))

Example

Reader Conditionals

Page 11: Clojure+ClojureScript Webapps

Language features „a la carte“

core.logic

core.async

clojure.spec

core.match Haskell style pattern matching

Logic programming

CSP style programming

Schematizing data

overtone SuperCollider synthesizers

Page 12: Clojure+ClojureScript Webapps

Functional programming meets the Real World(TM)

Pure functions

Side effects

Context

Page 13: Clojure+ClojureScript Webapps

Language & ToolingDemos of Webapps

Frontend ArchitectureRemoting

Backend Architecture

Overview

Page 14: Clojure+ClojureScript Webapps

ClojureScriptCompiler

LeiningenBuild Tool

SassCompiler

nREPL

clojure.jar

Java Virtual Machine

Figwheel

CIDEREmacs

Tooling

Page 15: Clojure+ClojureScript Webapps

Tooling

Sourcecode Browser REPL

JVM REPL

Page 16: Clojure+ClojureScript Webapps

Tooling

Sourcecode

Frontend

Browser Console

State

Page 17: Clojure+ClojureScript Webapps

Language & ToolingDemos of Webapps

Frontend ArchitectureRemoting

Backend Architecture

Overview

Page 18: Clojure+ClojureScript Webapps

Language & ToolingDemos of Webapps

Frontend ArchitectureRemoting

Backend Architecture

Overview

Page 19: Clojure+ClojureScript Webapps

Appstate

DOM

event

updates

mutations

Controller

e.g. Angular

transform

renderdiff + merge

DOM

Appstate

swap

React + Cljs Library

Virtual DOM

event

DOM operations are soooo sloooow.

It's not MVC as you know it

Page 20: Clojure+ClojureScript Webapps

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?

callback 1

callback 2

Page 21: Clojure+ClojureScript Webapps

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 22: Clojure+ClojureScript Webapps

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 23: Clojure+ClojureScript Webapps

Application Stateƒsubscription

ƒdispatch

ƒrender

BrowserDOM

Channel

ƒtransform

VirtualDOM

EventEvent

Current state

swap!

State

StateDOM

New state

Controller process

Big picture: uni-directional data flow

Page 24: Clojure+ClojureScript Webapps

Language & ToolingDemos of Webapps

Frontend ArchitectureRemoting

Backend Architecture

Overview

Page 25: Clojure+ClojureScript Webapps

Remote Communication: De-/Serialization

> (def msg {:service :add-contact :payload {:firstname "Foo" :lastname "Bar"}})

> (pr-str msg);= "{:service :add-contact, :payload {:firstname \"Foo\", :lastname \"Bar\"}}"

> (clojure.edn/read-string "{:service :add-contact, :payload {:firstname \"Foo\", :lastname \"Bar\"}}");= {:service :add-contact :payload {:firstname "Foo" :lastname "Bar"}}

Pro tip: use Cognitects Transit

Serialization

Deserialization

Data

Data

Page 26: Clojure+ClojureScript Webapps

Remote Communication: Frontend

core.async+

Transit+

POST

Page 27: Clojure+ClojureScript Webapps

Remote Communication: Backend

Friend-Authentication+

Transit-Middleware+

DIY Dispatching

Page 28: Clojure+ClojureScript Webapps

Language & ToolingDemos of Webapps

Frontend ArchitectureRemoting

Backend Architecture

Overview

Page 29: Clojure+ClojureScript Webapps

Webapp Backend

Small libraries,no big frameworks!

HTTPserver

Middle-warefunctions

Routingfunction

Handlerfunctions

Page renderer

Page 30: Clojure+ClojureScript Webapps

Component decouples backend code

System definition

Implementationnamespaces

Protocols+

Schemas/Types

Page 31: Clojure+ClojureScript Webapps

Wrap up

Page 32: Clojure+ClojureScript Webapps

Webapp development with Clojure + ClojureScript ...

... gives you rapid feedback

… provides a mature full-stack ecosystem

… is demanding to learn, but this will pay-off

Page 33: Clojure+ClojureScript Webapps

Thank you for listening!

Questions?

@friemens www.doctronic.de