clojure+clojurescript webapps

33
Webapps with Clojure & ClojureScript @friemens

Upload: falko-riemenschneider

Post on 10-Jan-2017

103 views

Category:

Technology


0 download

TRANSCRIPT

Webapps withClojure & ClojureScript

@friemens

Dear audience,a word of caution:

((((λ))))

Language & ToolingDemos of Webapps

Frontend ArchitectureRemoting

Backend Architecture

Overview

Language & ToolingDemos of Webapps

Frontend ArchitectureRemoting

Backend Architecture

Overview

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)

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

Why is Clojure a Lisp-style language?

Lisp!

Other Languages

Time

Expressive Power

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

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

Functional programming meets the Real World(TM)

Pure functions

Side effects

Context

Language & ToolingDemos of Webapps

Frontend ArchitectureRemoting

Backend Architecture

Overview

ClojureScriptCompiler

LeiningenBuild Tool

SassCompiler

nREPL

clojure.jar

Java Virtual Machine

Figwheel

CIDEREmacs

Tooling

Tooling

Sourcecode Browser REPL

JVM REPL

Tooling

Sourcecode

Frontend

Browser Console

State

Language & ToolingDemos of Webapps

Frontend ArchitectureRemoting

Backend Architecture

Overview

Language & ToolingDemos of Webapps

Frontend ArchitectureRemoting

Backend Architecture

Overview

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

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

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

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)))

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

Language & ToolingDemos of Webapps

Frontend ArchitectureRemoting

Backend Architecture

Overview

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

Remote Communication: Frontend

core.async+

Transit+

POST

Remote Communication: Backend

Friend-Authentication+

Transit-Middleware+

DIY Dispatching

Language & ToolingDemos of Webapps

Frontend ArchitectureRemoting

Backend Architecture

Overview

Webapp Backend

Small libraries,no big frameworks!

HTTPserver

Middle-warefunctions

Routingfunction

Handlerfunctions

Page renderer

Component decouples backend code

System definition

Implementationnamespaces

Protocols+

Schemas/Types

Wrap up

Webapp development with Clojure + ClojureScript ...

... gives you rapid feedback

… provides a mature full-stack ecosystem

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

Thank you for listening!

Questions?

@friemens www.doctronic.de