Introduction to Functional Reactive Web with Clojurescript

55
Introduction to Functional Reactive Web by John Stevenson @jr0cket practicalli.github.io/clojurescript

Transcript of Introduction to Functional Reactive Web with Clojurescript

Page 1: Introduction to Functional Reactive Web with Clojurescript

Introduction to Functional Reactive Web

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

Page 2: Introduction to Functional Reactive Web with Clojurescript

@jr0cketSpeaker, author, conference organiser & community obsessed

developer.

Love Clojure, Emacs, Cats, Cycling & Agile development.

@Heroku@SalesforceDevs

#Trailhead

In a galaxy far, far away…

Page 3: Introduction to Functional Reactive Web with Clojurescript

WhyFunctional Reactive Web

it's not just because it's really fun...

Page 5: Introduction to Functional Reactive Web with Clojurescript

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

Page 6: Introduction to Functional Reactive Web with Clojurescript

Side Effects

Page 7: Introduction to Functional Reactive Web with Clojurescript

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)

Page 8: Introduction to Functional Reactive Web with Clojurescript

Impure Functions - side causesThe results of the function are purely determined by its initial output and its own code

- behaviour externally influenced and non-deterministic

Page 9: Introduction to Functional Reactive Web with Clojurescript

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

Page 10: Introduction to Functional Reactive Web with Clojurescript

ClojureScript - Functional WebImmutability & composable functions for Web Apps

Page 11: Introduction to Functional Reactive Web with Clojurescript
Page 12: Introduction to Functional Reactive Web with Clojurescript
Page 13: Introduction to Functional Reactive Web with Clojurescript

jQuery over all JavaScript frameworks

Page 14: Introduction to Functional Reactive Web with Clojurescript
Page 15: Introduction to Functional Reactive Web with Clojurescript

Google Closure tools & libraries

Page 16: Introduction to Functional Reactive Web with Clojurescript
Page 17: Introduction to Functional Reactive Web with Clojurescript

ClojureScript Quickstart

Peeks under the covers of how to build and run Clojurescript generated JavaScript

Page 18: Introduction to Functional Reactive Web with Clojurescript
Page 19: Introduction to Functional Reactive Web with Clojurescript
Page 20: Introduction to Functional Reactive Web with Clojurescript

Getting Started with Clojurescript

Page 21: Introduction to Functional Reactive Web 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!

Page 22: Introduction to Functional Reactive Web with Clojurescript

Common Clojurescript Tooling

Figwheel (leiningen plugin)- defacto tool for client side web apps- live reload and so much more...

Figwheel-sidecar - connecting Emacs to figwheel

Page 23: Introduction to Functional Reactive Web with Clojurescript

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

Page 24: Introduction to Functional Reactive Web with Clojurescript

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/

Page 25: Introduction to Functional Reactive Web with Clojurescript

Understanding ReactBasic concepts of React

Page 27: Introduction to Functional Reactive Web with Clojurescript

React Basics

React provides an efficient way to update the view

Page 28: Introduction to Functional Reactive Web with Clojurescript

What React Provides

React is only the view

You DO NOT GET any of the following:

An event system (other than vanilla DOM events)Any AJAX capabilities whatsoeverAny form of a data layerPromisesAny application framework at allAny idea how implement the above

Page 29: Introduction to Functional Reactive Web with Clojurescript

How React Works (Simplified)

Your view triggers an event- a user types a name in a text field

That event updates a modelThen the model triggers an eventAnd the view responds to that model's event by re-rendering with the latest data.

This one way data flow / decoupled observer pattern is designed to guarantee that your source of truth always stays in your stores / models

Page 30: Introduction to Functional Reactive Web with Clojurescript

JSX

JSX is a preprocessor step that adds XML syntax to JavaScript.

You can definitely use React without JSX but JSX makes React a lot more elegant.

Just like XML, JSX tags have a tag name, attributes, and children.

If an attribute value is enclosed in quotes, the value is a string.

Page 31: Introduction to Functional Reactive Web with Clojurescript

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

Page 32: Introduction to Functional Reactive Web with Clojurescript

Javascript & Clojurescript frameworks

Javascript

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

Clojurescript

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

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

Page 33: Introduction to Functional Reactive Web with Clojurescript

ReagentInteractive development

Page 34: Introduction to Functional Reactive Web with Clojurescript

ReagentReagent provides a minimalistic interface between ClojureScript and React. It allows you to define efficient React components using nothing but plain ClojureScript functions and data, that describe your UI using a Hiccup-like syntax.

The goal of Reagent is to make it possible to define arbitrarily complex UIs using just a couple of basic concepts, and to be fast enough by default that you rarely have to care about performance.

Page 35: Introduction to Functional Reactive Web with Clojurescript

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

Page 36: Introduction to Functional Reactive Web with Clojurescript

Reagent Helper functions

clj->js- convert values from clojurescript to javascript

js->clj- transforms JavaScript arrays into ClojureScript vectors, and JavaScript objects into ClojureScript maps

Page 37: Introduction to Functional Reactive Web with Clojurescript

ReframeA micro-framework for Reagent

Page 38: Introduction to Functional Reactive Web with Clojurescript

Reframere-frame is a pattern for writing SPAs in ClojureScript, using Reagent.

Being a functional framework, it is about data, and the (pure) functions which transform that data.

It is a loopArchitecturally, re-frame implements "a perpetual loop".

To build an app, you hang pure functions on certain parts of this loop, and re-frame looks after the conveyance of data around the loop, into and out of the transforming functions you provide - hence a tag line of "Derived Values, Flowing".

Page 39: Introduction to Functional Reactive Web with Clojurescript

Om / Om-nextClojureScript interface to Facebook's React

Page 40: Introduction to Functional Reactive Web with Clojurescript

Om / Om-nextOm allows users to represent their UIs simply as EDN. Because ClojureScript data is immutable data, Om can always rapidly re-render the UI from the root. Thus Om UIs are out of the box snapshotable and undoable and these operations have no implementation complexity and little overhead.

See for yourself.

Unique FeaturesOm 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 can be intercepted via :instrument. Simplifies debugging components and generic editors.● Provides stream of all application state change deltas via :tx-listen. Simplifies synchronization online and offline.● Customizable semantics. Fine grained control over how components store state, even for components outside of your control.

Simplifies using Om components outside the Om framework, debugging, and adding event hooks not anticipated by original component designer.

Page 41: Introduction to Functional Reactive Web with Clojurescript

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

Page 42: Introduction to Functional Reactive Web with Clojurescript

Om Cursors

Cursors are a fundamental part of Om. They let components refer to pieces of the app state without knowing where they are in the state tree. This makes updating the app state simple, as the cursor is already pointing to the correct part of the app state.

cursors are like maps, but cursors also let you write to them

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

appstate :entries 0

Page 43: Introduction to Functional Reactive Web with Clojurescript

RumA micro-framework for Reagent

Page 44: Introduction to Functional Reactive Web with Clojurescript

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

Page 45: Introduction to Functional Reactive Web with Clojurescript

ClojureScript DemoInteractive development

Page 46: Introduction to Functional Reactive Web with Clojurescript

Figwheel (flappy birds example)

Page 47: Introduction to Functional Reactive Web with Clojurescript

Take your own journey into Clojure

Page 49: Introduction to Functional Reactive Web with Clojurescript

Clojure - Functional WebImmutability & composable functions for Web Apps

Page 50: Introduction to Functional Reactive Web with Clojurescript

Ring - simplifying communication

Ring takes requests over HTTP and converts them into a map (think JSON)

Page 51: Introduction to Functional Reactive Web with Clojurescript

Ring - creating an embedded server

Page 52: Introduction to Functional Reactive Web with Clojurescript

Compojure - simplifying routingCompojure routes requests based on path & request type

Page 53: Introduction to Functional Reactive Web with Clojurescript

Compojure - defining routes

Page 54: Introduction to Functional Reactive Web with Clojurescript

Hiccup - html from Clojure

Page 55: Introduction to Functional Reactive Web with Clojurescript

Ring - embedded server & dependencies