progscon 2017: taming the wild fronteer - adventures in clojurescript

Post on 23-Jan-2018

531 Views

Category:

Technology

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Taming the wild fronteerAdventures in Clojurescript

by John Stevenson @jr0cket practicalli.github.io/clojurescript

@jr0cketSpeaker, author, conference organiser

& community obsessed developer.

Loves Clojure, Spacemacs, Cats, Cycling & Agile development.

@Heroku@SalesforceDevs

In a galaxy far, far away…

Taming The Wild FronteerJavascript is a highly pervasive platform...

Javascript as a platform is everywhere

@jr0cket

Many programming languages have their quirks…

@jr0cket

www.destroyallsoftware.com/talks/wat

A common view of Javascript as a language

@jr0cket

ClojureScriptA general purpose language made from decades of design

From Javascript to Clojurescript

f(x) -> (f x);; First element of a list is a function call

var foo = “bar” -> (def foo “bar”);; bind a name to a value or function

@jr0cket

Clojurescript - basic syntax(ns clojure.awesome ) ;; define a namespace (scoping)

(defn function-name [args] (behaviour)) ;; define a function, with arguments(function-name data) ;; call a function with the data as its argument

(def name “data-or-value”) ;; bind a name to data within the namespace scope(let [name “data-or-value”]) ;; bind a name to a data within the let scope (local)

:keyword-name ;; a keyword is a name (symbol) that points to itself

;; Chaining functions: Thread the result of the first fn into the argument of the next fn (-> (function-a “data”) (function-b ,,,) ;; In Clojure commas , are whitespace (function-c ,,, “data”))

Built-in immutable data structures

Model state and any other data with built-in (hash) maps, vectors (arrays), (linked) lists, (unique) sets

(list 1 2 3 4 5) ‘(“fish” “chips” 42)

(vec ‘(1 2 3 4)) [1 2 3 4]

{:key “value”} {:name “John” :skill “conferencing”}

(set ‘(1 2 3 4 4)) #{1 2 3 4}

Clojure - a few core functions(map fn collection) ;; map a fn over a collection, return new collection(reduce fn collection) ;; return the value of combining elements in collection with fn

(for [x collection] (fn x)) ;; iterate over the elements of a collection

(filter fn collection) ;; return a collection of values that comply with the filter fn

(get {:veg “kale” :fruit “kiwi”} :fruit) ;; return value pointed to by keyword(:fruit {:veg “kale” :fruit “kiwi”}) ;; return value pointed to by keyword

(conj collection value) ;; conjoin a value to the collection(assoc collection coll) ;; add a collection to the collection(update {:a 1} :a fn) ;; update value pointed to by the key in a map with the fn

ClojureScript:Managing complexityA pragmatic approach to purity

The Complexity Iceberg

- @krisajenkins

● complexity is very dangerous when hidden

● You can't know what a function does for certain if it has side effects

Side Effects

Pure FunctionsThe results of the function are purely determined by its initial output and its own code

- no external influence, a function only uses local values- referential transparency (the function can be replaced by its value)

Impure Functions - side causes

Eliminating Side Effects

Functional programming is about eliminating side effects where you can, controlling them where you can't - @krisajenkins

The features in Functional Programming come from a desire to reduce side effects

Design idiom:Composing functions together

You can think of functional design as evaluating one or more functions in series of functions

The Map Reduce Sandwich

Clojure - the Map Reduce Sandwich

Clojure - the Map Reduce Sandwich

Pure Functions & Immutability = ParallelismIn simple terms: run the same code across multiple CPU’s / Threads

Parallelism - pmappmap - the same as map but in parallel

Parallelism - reduceSignificantly lower completion time running in parallel using Immutable data structures

https://github.com/aphyr/tesser

Managing StateState changes should be managed easily

Safe State changes

Changing state safely by changing it atomically

● Software Transactional Memory (STM)○ Gives an mechanism like an in-memory atomic database that manages mutable state changes

under the covers

● Atoms● Refs● core.async

Concurrency syntax - atoms

An online card game has players that can join and have their winnings tracked

Concurrency syntax - atoms

The join-game function adds players to the atom by their name, but only up to 2 players

Concurrency syntax - refsjoin-game-safely adds players to ref & alters their account & game account

ClojureScript - Functional WebImmutability & composable functions for Web Apps

See Clojurescript for Skeptics: https://www.youtube.com/watch?v=gsffg5xxFQI&t=4s

jQuery over all JavaScript frameworks

See Clojurescript for Skeptics: https://www.youtube.com/watch?v=gsffg5xxFQI&t=4s

See Clojurescript for Skeptics: https://www.youtube.com/watch?v=gsffg5xxFQI&t=4s

Google Closure tools & libraries

See Clojurescript for Skeptics: https://www.youtube.com/watch?v=gsffg5xxFQI&t=4s

Examples of Clojurescript

● Goya - pixel editor with undo https://jackschaedler.github.io/goya/

● CircleCI● Style.com● Klipse - web-based dev tool

& library for live-code examples in blogs / workshops

Getting Started with Clojurescript

Clojurescript Environments

Nashorn- built into JVM, access Java classes- Oracle Nashorn: A Next-Generation JavaScript Engine for the JVM

Browser-REPL- built into modern browsers (Chrome, Firefox, etc)- commonly used for client side web apps

Node.js- great for command line utilities and microservices!

Common Clojurescript Tooling

Leiningen- build automation tool for Clojure & Clojurescript

Figwheel (leiningen plugin)- defacto tool for client side web apps- live reload- multi-broadcast (eg simultaneous dev & test outputs)

Full-stack projects: Chestnut

https://github.com/plexus/chestnut- leiningen template for Clojure/ClojureScript apps based- with Om, Reagent, or Rum- instant reloading of Clojure, ClojureScript, and CSS- browser-connected REPL included

lein new chestnut project-name

Self-hosted Clojurescript Environments

Instant startup times, great for command line tools

Lumo (cross-platform)- https://github.com/anmonteiro/lumo

Plank (Mac & Linux)- http://planck-repl.org/

Understanding ReactBasic concepts of React

React Basics (conceptual)

React provides an efficient way to update the view

What React Provides

React is only the view

The view should update the state,not the DOM

Reactive FrameworksAll the varieties of life, plus all the Javascript varieties too...

Javascript & Clojurescript frameworks

Javascript

● React.js via cljsjs● Vue.js ???

Clojurescript

● Om / Om-next● Reagent / Reframe● Rum

More at https://clojurescript.org/community/libraries

React.jsUsing React.js within Clojurescript

Simple Calculator with React.js

Reagent

Clojurescript can directly use the React.js library thanks to cljsjs.github.io

React.js

React.js

React.js

React.js

React.js

React.js

Om / Om-nextClojureScript interface to Facebook's React

Om / Om-nextModels the React.js API

Rapidly re-render the UI from the root due via Immutable data structures- UIs are snapshot-able and undoable without implementation complexity

Om supports features not currently present in React:

- Global state management facilities built in- Components may have arbitrary data dependencies, not limited to props & state- Component construction intercepted via :instrument. Simplifies debugging - Stream all application state deltas via :tx-listen. Simplifies on/offline sync- Customizable semantics

Om core functions

om.core/IRender- Render a Om component into the DOM- uses reify to provide a specific implementation of the om/IRender interface

om.core/IInitState- maintains a local state (eg. for managing user input data)

om.core/IRenderState- Render a Om component into the DOM- renders component on change in local & global state

Om core functions

om.dom/div attributes content- creates a <div> tag in react- all react tags need to be wrapped in a div in order to be rendered- om.dom/… has all the other tags too - h1, h2, p, a … (sablono can be used instead)

#js- converts clojure maps into Javascript objects- nest #js functions to to create JS objects - eg. for inline styles

Om Cursors

A cursor is an atom & a path to a location in the atom

app-state :schedule 0

Components use the cursor to refer to pieces of the app state - without knowing where they are in the state tree- updating app state is simple as the cursor is in the correct part of the app state

ReagentInteractive development

Reagent

Reagent provides a minimalistic interface between ClojureScript and React

- define efficient React components using nothing but plain ClojureScript functions and data

- describe your UI using a Hiccup syntax [:div [:h1 “Heading”] [:div [:p “Paragraph” ] [:a {:href “/link.html”} “link text”]]]

- define arbitrarily complex UIs using a couple of basic concepts- fast enough by default that you rarely have to care about performance.

Reagent Core functions

reagent.core/render- Render a Reagent component into the DOM- First argument is either a vector (Reagent Hiccup syntax) or a React element

reagent.core/atom- Like clojure.core/atom, plus it tracks components that deref atom & re-renders them

Helper functions

Reagent used Clojurescript functions for conversion from- Clojure Maps to Javascript Objects - Clojurescript vectors to Javascript arrays

clj->js- convert from Clojurescript to Javascript

js->clj- convert from Javascript to Clojurescript

Reagent Examples

http://timothypratley.blogspot.co.uk/2017/01/reagent-deep-dive-part-1.html

- Uses Klipse to display interactive code snippets for Reagent- Includes use of SVG and Web3D libraries too

Graph example - http://leaderboardx.herokuapp.com/

ReframeA micro-framework for Reagent

Re-frame

a pattern for writing SPAs in ClojureScript, using Reagent.

a framework with pure functions which transform data

Architecturally implements "a perpetual loop".

Build apps by writing pure functions for certain parts of the loop that transform the data - Re-frame looks after the conveyance of data around the loop, into and out of the transforming functions you write - tag line of "Derived Values, Flowing".

RumA micro-framework for Reagent

RumRum is a client/server library for HTML UI. In ClojureScript, it works as React wrapper, in Clojure, it is a static HTML generator.

- Simple semantics: Rum is arguably smaller, simpler and more straightforward than React itself.

- Decomplected: Rum is a library, not a framework. Use only the parts you need, throw away or replace what you don’t need, combine different approaches in a single app, or even combine Rum with other frameworks.

- No enforced state model: Unlike Om, Reagent or Quiescent, Rum does not dictate where to keep your state. Instead, it works well with any storage: persistent data structures, atoms, DataScript, JavaScript objects, localStorage or any custom solution you can think of.

- Extensible: the API is stable and explicitly defined, including the API between Rum internals. It lets you build custom behaviours that change components in significant ways.

- Minimal codebase: You can become a Rum expert just by reading its source code (~900 lines).

Rum - at ClojureX

https://skillsmatter.com/skillscasts/9149-modern-web-apps-with-rum

Other ClojureScript examplesInteractive development

Figwheel (flappy birds example)

Take a journey into Clojurescript

Clojurescript.org & ClojureDocs.org

londonclojurians.org

- 4 events per month- Possibly the most active language-specific

developer communitie in London

Learning by teaching others

I really started thinking in Clojure when I started talking to & teaching others

- Coding dojos- talks on Clojure (starting with the basics, showing the art of the possible)- moving on to running conferences- workshops at hack days

Thank you

@jr0cketjr0cket.co.uk

slideshare.net/jr0cket

You unlock this door with

the key of imagination,

Beyond it is another

dimension

… a dimension of sound

Sound design of a language evolved over many

years

… a dimension of sight

REPL driven development showing you clearly

what your code is doing

… a dimension of mind

Thinking Functionally, of pure functions &

immutability

… of things and ideas

Merging of data structures & behaviour in one

syntax - homoiconicity

You have just crossed over to...

The Clojurescript Zone

The boundaries are only your imagination

top related