Resource Dashboard

there will be no maths ...

Problems with most* UI development

  • spaghetti
  • two-way data flow
  • rampant mutation
  • expensive change tracking
  • performance

* yes ours too

- Rich Hickey -

The role of functional programming

  • FP programs are compositions of pure functions with strictly contained side effects
  • ​Pure functions are easy to test, easy to parallelise, easy to refactor
  • FP programs are predictable
  • FP favours immutable data

How does this solve the UI problem?

  • An app or site is a composition of UI components
  • A UI component is a pure function that accepts application state and returns a representation of the UI
  • Same state -> same UI
  • Different state -> new UI

Has anyone done this for us?

  • Facebook with React framework?
  • Gives us a one way data flow
  • Components can be regarded as pure functions
  • Virtual DOM is the much copied secret sauce
  • One way flow + vdom + immutable data == FAST

Why Clojure?

* puke
  • Very well designed simple lisp - we all “transpile*” anyway
  • powerful meta programming capabilities
  • code is data
  • “Isomorphic*”
  • Functional slant
  • Immutable by default with good concurrency primitives
  • Live coding
  • Fun
  • Hiccup - html is code not a string (can be transformed)

A crash course in clojure ...

(
func
(
func2 arg arg)
)
arg

start s-expression

first form is always a function

then come the arguments

which can be function calls

#
(
func3 arg arg)

or lambdas

close s-expression

Notice that this whole thing is itself a list: 

codeception

Why Reagent?

  • A super simple wrapper around react
  • Very nice hiccup style templating
(defn simple-parent []
  [:div
   [:p "I include simple-component."]
   [simple-component]])
(defn hello-component [name]
  [:p "Hello, " name "!"])

(defn say-hello []
  [hello-component "world"])
(ns example
  (:require [reagent.core :as reagent :refer [atom]]))
(def click-count (atom 0))

(defn counting-component []
  [:div
   "The atom " [:code "click-count"] " has value: "
   @click-count ". "
   [:input {:type "button" :value "Click me!"
            :on-click #(swap! click-count inc)}]])
(ns example
  (:require [reagent.core :as reagent :refer [atom]]))
(defn atom-input [value]
  [:input {:type "text"
           :value @value
           :on-change #(reset! value (-> % .-target .-value))}])

(defn shared-state []
  (let [val (atom "foo")]
    (fn []
      [:div
       [:p "The value is now: " @val]
       [:p "Change it here: " [atom-input val]]])))

Why Re-frame?

  • provides a simple and magical way to manage state

;;subscriptions

(register-sub :paging
    (fn [db _]
        (reaction (:paging @db)))))
;;component
(defn pager []
  (let [paging (subscribe [:paging])]
    (fn []
      (let [index (:index @paging)
            size (:size @paging)
            total (:total @paging)
            pages (.ceil js/Math (/ total size))
            start (* index size)
            end (+ start size)]
      [:ul.pager
       [:li {:className (if (= index 0) "disabled") }
        [:a {:on-click #(when (> index 0) ( dispatch [:change-page dec]))
             :href "#"} [:i.fa.fa-arrow-left] "  Previous"]]
       [:li.record-count (str "page " (inc index) " of "  pages  " (" total " resources)")]
       [:li {:className (if (= pages (inc index)) "disabled") }
        [:a {:on-click #(when (< (inc index) pages) ( dispatch [:change-page inc]))
             :href "#"} "Next  " [:i.fa.fa-arrow-right]]]]))))
;;message handler
(register-handler
  :change-page 
  (fn [db [_ op]]
    (let [i (get-in db [:paging :index])
          paging (assoc (get db :paging) :index (op i))]
     (search (:search db) paging :search-results)
      (assoc db :paging paging))))
Not everything
is awesome
  • testing
  • debugging
  • THE BRACKETS!
  • learning curve

Should we do this?

  • Yes and no
  • Maybe
  • Probably not
  • We should be inspired by it

Questions?

https://github.com/clojure/clojurescript
https://github.com/Day8/re-frame
http://facebook.github.io/react/
https://reagent-project.github.io/index.html

References

  • Demo (repl [doc, source, js/alert], render function, interactive message dispatch, add new mode)
  • It there's time - have a look at the server.
  • Explain a bit about compojure, edn, YESQL ...
  • Talk about tools editors (vim, fireplace, lightable, cursive)

Resource Dashboard

By Julian Jelfs

Resource Dashboard

Part two of resource dashboard presentation. This is a deeper look at the technology that sits behind it and an examination of the problems that this approach might solve.

  • 84