Priyatam Mudivarti
Principal, Facjure
REPL
Understanding (parens)
Data Structures
Functions, Closures, HoF
Data Flow
HTML5
CSS3
Templating
IDEs
Libraries
Templates
client apis
Build Tools
Responsive Design
Events
Dom
Performance
Modules
3rd party libs
Javascript
event handling, dynamic, ajax, json
CSS3/Less/Sass
rules, selectors,
responsive design
HTML5
markup , templating, dom
build plugins
mvc frameworks
modules
load-times
bundling
3rd party "functional" libs
optimization (dead code elimination)
functions that create sequences
functions that filter sequences
sequence predicates
functions that transform sequences
;; Unlike JavaScript there is no hoisting in ClojureScript. ClojureScript has lexical scoping.
(def some-x 1)
(let [some-x 2]
some-x)
;; functions parameters, let bindings locals, and loop locals are not mutable!
(let [fns (loop [i 0 ret []]
(if (< i 10)
(recur (inc i) (conj ret (fn [] i)))
ret))]
(map #(%) fns))
; simple function
(defn add [a b]
(+ a b))
;; function with multiple args and default values
(defn another-function
([x] (defaults x :default))
([x y] [x y]))
;; closure
(let [a 1e3]
(defn foo []
(* a a))
(defn bar []
(+ (foo) a)))
;; higher order functions
(def a-vector [1 2 3 4 5])
(def a-nested-map
{:customer-id 1e6
:preferences {:nickname "Bob"
:avatar "http://en.gravatar.com/userimage/0/0.jpg"}
:services {:alerts {:daily true}}})
(def complex-map
{[1 2] :one-two
[3 4] :three-four})
(def a-set
#{:cat :dog :bird})
(defn clearfix [clazz]
[clazz {:*zoom 1}
[:&:before :&:after {:display "table"
:content " "
:line-height 0}]
[:&:after {:clear "both"}]])
[
{:poem/title "I am not a hacker"}
{:poem/book :poets-and-hackers}
{:poem/year 2015}
{:author/name "Priyatam Mudivarti"}
{:author/email "priyatam@facjure.com"}
{:author/gender :male}
{:tag/names #{:hackers :poetry-slam :boulder-cafe :fp-rocks}
{[1 2] :one-two }}
]
[
{:poem/title "I am not a hacker"}
{:poem/book :poets-and-hackers}
{:poem/year 2015}
{:author/name "Priyatam Mudivarti"}
{:author/email "priyatam@facjure.com"}
{:author/gender :male}
{:tag/names #{:hackers :poetry-slam :boulder-cafe :fp-rocks}
{[1 2] :one-two }}
]
(def header-snippet
[:header
[:h1 "Mala"]
[:h3 "A User Interface template in Clojurescript."]])
(def footer-snippet
[:footer
[:a {:href "https://twitter.com/priyatam"} "@priyatam"]])
(defn view [{:keys [active path name]}]
(html
[:section {:class "home"}
header-snippet
[:nav
[:ul
[:li {:class (if active "active" "")}
[:a {:href (str "#" path)} name]]]]
footer-snippet]))
;; Plain old Ajax
(defn handler [response]
(.log js/console (str response)))
(defn error-handler [{:keys [status status-text]}]
(.log js/console (str "something bad happened: " status " " status-text)))
(GET "/hello" {:handler handler
:error-handler error-handler})
;; Core.Async
(defn GET [res handler]
(go (let [response (<! (http/get res {:with-credentials? false}))]
(logp (:body response))
(handler (:body response)))))
(ns brutha.example
(:require [brutha.core :as br :refer [mount]]
[sablono.dom :as dom]))
(mount
(html [:p "Hello World"])
(js/document.getElementById "app"))
;; list comprehension
(for [x (range 1 10)
y (range 1 10)
:when (and (zero? (rem x y))
(even? (quot x y)))]
[x y])
;; higher order functions over sequences
(map inc [0 1 2 3 4 5 6 7 8 9])
(filter even? (range 10))
(reduce + (range 100))
(partition 2 [:a 1 :b 2 :c 3 :d 4 :e 5])
(remove odd? (range 10))
(take 5 (interleave (repeat "red") (repeat "blue")))
Abstraction is at the center of most work in
Computer Science &
User Interface Design.
(map
(comp - (partial + 3) (partial * 2))
[1 2 3 4])
;;=> (-5 -7 -9 -11)
no namespaces
can't compose HTML and CSS in the same syntax
css doesn’t “talk to dom”
math impl is hard
can we pass css as functions at runtime?
mixins are not composable
constrained by limitations—not by choice
programming stylesheets
in FP
separate selectors and declarations
Ring-style middleware
http://github.com/facjure/mesh
(defn create-minimal-grid [clazz pad]
[[:* {:box-sizing "border-box"}]
[clazz {:background "white"
:margin [[0 0 pad 0]]}
[:&:after {:content ""
:display "table"
:clear "both"}]
["[class*='col-']" {:float "left"
:padding-right pad }]
[:.col-1-3 {:width "33.33%"}]
[:.col-2-3 {:width "66.66%"}]
[:.col-1-2 {:width "50.00%"}]
[:.col-1-4 {:width "25.00%"}]
[:.col-1-8 {:width "12.50%"}]
[:.out-padding {:padding [[pad 0 pad pad pad]]}
["[class*='col-']:last-of-type"
{:padding-right pad}]]]])
markup in cljs data structures
styles in clojurescript data structures
event handling as functions
markup in cljs data structures
styles in clojurescript data structures
event handling as functions
single-page app with html5 local-storage
css3
Demos created with https://github.com/priyatam/mala
https://github.com/facjure/mesh Libraries https://github.com/omcljs/om https://github.com/noprompt/garden https://github.com/noprompt/secretary
https://github.com/bhauman/lein-figwheel
https://slides.com/priyatam/functional-programming-with-cljs
@priyatam
priyatam@facjure.com
http://github.com/priyatam