SlideShare a Scribd company logo
ClojureScript
for the web
Michiel Borkent
@borkdude
Øredev, November 6th 2014
Michiel Borkent (@borkdude)
● Clojure(Script) developer at
● Clojure since 2009
● Former lecturer, taught Clojure
Agenda
● Why ClojureScript?
● The Language
● The Ecosystem
Warning
Why ClojureScript?
Current status
● JavaScript is everywhere, but not a robust and concise
language - wat
Requires discipline to only use "the good parts"
● JavaScript is taking over: UI logic from server to client
● JavaScript is not going away in the near future
● Advanced libraries and technologies exist to optimize
JavaScript: (Google Closure, V8)
tl;dr:
● complexity is biggest problem in software
● mutability + control: more state, more complexity
● immutability + FP: less state, less complexity
Clojure(Script) promotes
source: http://www.drdobbs.com/architecture-and-design/the-clojure-philosophy/240150710
ClojureScript?
● Released June 20th 2011
● Client side story of Clojure ecosystem
● Serves Clojure community:
50%* of Clojure users also use ClojureScript
93%** of ClojureScript users also use Clojure
● ClojureScript targets JavaScript by adopting Google
Closure
○ libraries: goog.provide/require etc.
○ optimization: dead code removal
*http://cemerick.com/2013/11/18/results-of-the-2013-state-of-clojure-clojurescript-survey/
** http://blog.cognitect.com/blog/2014/10/24/analysis-of-the-state-of-clojure-and-clojurescript-survey-2014
The Language
Such parens...
f(x) -> (f x)
JavaScript - ClojureScript
no implementation (ns my.library
(:require [other.library :as other]))
var foo = "bar"; (def foo "bar")
// In JavaScript
// locals are mutable
function foo(x) {
x = "bar";
}
;; this will issue an error
(defn foo [x]
(set! x "bar"))
source: http://himera.herokuapp.com/synonym.html
JavaScript - ClojureScript
if (bugs.length > 0) {
return 'Not ready for release';
} else {
return 'Ready for release';
}
(if (pos? (count bugs))
"Not ready for release"
"Ready for release")
var foo = {bar: "baz"};
foo.bar = "baz";
foo["abc"] = 17;
(def foo (js-obj "bar" "baz"))
(set! (.-bar foo) "baz")
(aset foo "abc" 17)
source: http://himera.herokuapp.com/synonym.html
Core language features
● persistent immutable data structures
● functional programming
● sequence abstraction
● isolation of mutable state (atoms)
● Lisp: macros, REPL
● core.async
Persistent data structures
(def v (vector))
(def v [])
(def v [1 2 3])
(conj v 4) ;; => [1 2 3 4]
(get v 0) ;; => 1
(v 0) ;; => 1
source: http://hypirion.com/musings/understanding-persistent-vector-pt-1
Persistent data structures
(def m (hash-map))
(def m {})
(def m {:foo 1 :bar 2})
(conj m [:baz 3])
;; => {:foo 1 :bar 2 :baz 3}
(assoc m :foo 2) ;; => {:foo 2 :bar 2}
(get m :foo) ;;= > 2
(m :foo) ;;= > 2
(dissoc m :foo) ;;=> {:bar 2}
Functional programming
(def r (->>
(range 10) ;; (0 1 2 .. 9)
(filter odd?) ;; (1 3 5 7 9)
(map inc))) ;; (2 4 6 8 10)
;; r is (2 4 6 8 10)
Functional programming
;; r is (2 4 6 8 10)
(reductions + r)
;; => (2 6 12 20 30)
(reduce + r)
;; => 30
Sequence abstraction
Data structures as seqs
(first [1 2 3]) ;;=> 1
(rest [1 2 3]) ;;=> (2 3)
General seq functions: map, reduce, filter, ...
(distinct [1 1 2 3]) ;;=> (1 2 3)
(take 2 (range 10)) ;;=> (0 1)
See http://clojure.org/cheatsheet for more
Sequence abstraction
Most seq functions return lazy sequences:
(take 2 (map
(fn [n] (js/alert n) n)
(range))) infinite lazy sequence of numbers
side effect
Isolation of state
adapted from: https://github.com/dfuenzalida/todo-cljs
one of possible
pre-React
patterns
function called
from event
handler
(def app-state (atom []))
(declare rerender)
(add-watch app-state ::rerender
(fn [k a o n]
(rerender o n)))
(defn add-todo [text]
(let [tt (.trim text)]
(if (seq tt)
(swap! app-state conj
{:id (get-uuid)
:title tt
:completed false}))))
new todo
Lisp: macros
(map inc
(filter odd?
(range 10))))
(->>
(range 10)
(filter odd?)
(map inc))
thread last macro
Lisp: macros
(macroexpand
'(->> (range 10) (filter odd?)))
;; => (filter odd? (range 10))
(macroexpand
'(->> (range 10) (filter odd?) (map inc)))
;; => (map inc (filter odd? (range 10)))
Lisp: macros
JVM Clojure:
(defmacro defonce [x init]
`(when-not (exists? ~x)
(def ~x ~init)))
ClojureScript:
(defonce foo 1)
(defonce foo 2) ;; no effect
notes:
● macros must be written in JVM Clojure
● are expanded at compile time
● generated code gets executes in ClojureScript
LISP: Browser REPL (weasel)
core.async
(def ch (chan))
(go (loop []
(if-let [msg (<! ch)]
(do
(.log js/console msg)
(recur))
(println "terminating loop..."))))
(events/listen (by-id "button1") EventType.CLICK
#(put! ch "hello world!"))
(events/listen (by-id "button2") EventType.CLICK
#(close! ch))
The Ecosystem
Debugging
Source maps let you debug ClojureScript directly from the browser
Leiningen
● Used by 98% of Clojure users
● Clojure's Maven
● Managing dependencies
● Running a REPL
● Packaging and deploying
● Plugins:
○ lein cljsbuild
○ lein figwheel
(defproject example "0.1.0-SNAPSHOT"
:description "FIXME: write this!"
:url "http://example.com/FIXME"
:dependencies [[org.clojure/clojure "1.6.0"]
[org.clojure/clojurescript "0.0-2311"]]
:plugins [[lein-cljsbuild "1.0.4-SNAPSHOT"]]
:source-paths ["src"]
:cljsbuild {:builds [{:id "example"
:source-paths ["src"]
:compiler {
:output-to "example.js"
:output-dir "out"
:optimizations :none
:source-map true}}]})
figwheel: live code reloading
Editors
Most popular:
● Emacs
● Cursive Clojure
(IntelliJ)
● Vim + vim-fireplace
● Light Table
● Counterclockwise
(Eclipse)
cljs.core.typed
(ns foo)
(ann parse-int [string -> number])
(defn parse-int [s]
(js/parseInt s))
(parse-int 3)
Function foo/parse-int could not be
applied to arguments:
Domains:
string
Arguments:
(clojure.core.typed/Val 3)
Ranges:
number
in: (foo/parse-int 3)
ClojureScript interfaces to React
Talk today @ 17:40-18:20
(defn timer-component []
(let [seconds-elapsed (atom 0)]
(fn []
(js/setTimeout #(swap! seconds-elapsed inc) 1000)
[:div
"Seconds Elapsed: " @seconds-elapsed])))
Community
Google Groups
IRC: #clojure and #clojurescript on freenode
Planet Clojure
Reddit
Meetup.com
Interesting libraries
● cljs-http: ajax + core.async
● cljx: code sharing between clj and cljs
● clojurescript.test: unit testing
● dommy: dom manipulation
● crate: hiccup style HTML templating
● sente: websockets + core.async
● transit: conveying values between languages
● datascript: functional database in cljs
● garden: css generation from Clojure
Thank you!
https://github.com/borkdude/oredev2014
Trash can
ClojureScript for the web
June 20th 2011: first release of ClojureScript
Brief history of ClojureScript
Brief history of ClojureScript
Early 2012: first release of lein cljsbuild
Leiningen plugin to make ClojureScript development easy
98% of Clojure users use Leiningen
Possible optimization levels include
:whitespace removes comments and whitespace
:simple renames local variables to compress JavaScript
:advanced: agressively renames and strips away unused
Brief history of ClojureScript
April 2012:
persistent data structures were ported
Light Table
June 2012
Funded as Kickstarter Project
Interactive, experimental IDE written in
ClojureScript, running on Node Webkit
Became open source early 2014
Brief history of ClojureScript
October 2012: ClojureScript Up and Running - O'Reilly
Brief history of ClojureScript
August 2014
Transducers
(->>
(range 10)
(filter odd?)
(map inc))
(def xform
(comp
(filter odd?)
(map inc)))
;; lazy
(sequence xform
(range 10))
;; strict
(into [] xform (range 10))
core.async
transducers
EDN
ClojureScript
persistent data
structures
(immutable)
atoms (mutable)
Generated
optimized
JavaScript
Google
Closure
JavaScript
libraries
your program
Compiler
ClojureScript libs
Lisp: macros
(if (< x 5)
:foo
(if (> x 10)
:bar
:baz))
(cond (< x 5) :foo
(> x 10) :bar
:else :baz)
cond macro
Frameworks
● Pedestal
● Hoplon
● Luminus (curated collection of libs)

More Related Content

PDF
ClojureScript loves React, DomCode May 26 2015
PDF
Full Stack Clojure
PDF
ClojureScript interfaces to React
PPTX
Functional Reactive Programming with RxJS
PDF
Exploring Clojurescript
PDF
Wprowadzenie do technologii Big Data / Intro to Big Data Ecosystem
PDF
Clojure+ClojureScript Webapps
PPTX
Lua: the world's most infuriating language
ClojureScript loves React, DomCode May 26 2015
Full Stack Clojure
ClojureScript interfaces to React
Functional Reactive Programming with RxJS
Exploring Clojurescript
Wprowadzenie do technologii Big Data / Intro to Big Data Ecosystem
Clojure+ClojureScript Webapps
Lua: the world's most infuriating language

What's hot (20)

PDF
Hw09 Hadoop + Clojure
PDF
Hadoop + Clojure
PDF
Coroutines in Kotlin. UA Mobile 2017.
PDF
Pune Clojure Course Outline
PDF
Coroutines in Kotlin
PDF
Cluj.py Meetup: Extending Python in C
PPTX
Luis Atencio on RxJS
PDF
Kirk Shoop, Reactive programming in C++
PDF
Minion pool - a worker pool for nodejs
PDF
Parallel R in snow (english after 2nd slide)
PDF
When RegEx is not enough
PDF
Cluj Big Data Meetup - Big Data in Practice
PDF
From Zero to Application Delivery with NixOS
PDF
PyCon KR 2019 sprint - RustPython by example
PDF
Php 5.6 From the Inside Out
PPTX
Naughty And Nice Bash Features
PDF
Asynchronous single page applications without a line of HTML or Javascript, o...
ODP
Clojure made really really simple
PDF
Powered by Python - PyCon Germany 2016
PDF
DConf 2016: Keynote by Walter Bright
Hw09 Hadoop + Clojure
Hadoop + Clojure
Coroutines in Kotlin. UA Mobile 2017.
Pune Clojure Course Outline
Coroutines in Kotlin
Cluj.py Meetup: Extending Python in C
Luis Atencio on RxJS
Kirk Shoop, Reactive programming in C++
Minion pool - a worker pool for nodejs
Parallel R in snow (english after 2nd slide)
When RegEx is not enough
Cluj Big Data Meetup - Big Data in Practice
From Zero to Application Delivery with NixOS
PyCon KR 2019 sprint - RustPython by example
Php 5.6 From the Inside Out
Naughty And Nice Bash Features
Asynchronous single page applications without a line of HTML or Javascript, o...
Clojure made really really simple
Powered by Python - PyCon Germany 2016
DConf 2016: Keynote by Walter Bright
Ad

Similar to ClojureScript for the web (20)

PDF
Progscon 2017: Taming the wild fronteer - Adventures in Clojurescript
PDF
ClojureScript - Making Front-End development Fun again - John Stevenson - Cod...
PDF
The Ideas of Clojure - Things I learn from Clojure
PDF
HelsinkiJS - Clojurescript for Javascript Developers
PDF
Functional web with clojure
PDF
Introduction to Clojure
PDF
A Taste of Clojure
PPTX
Clojure 7-Languages
PDF
Clojure and The Robot Apocalypse
ODP
Getting started with Clojure
PDF
Clojure made-simple - John Stevenson
PPTX
Why clojure(script) matters
PDF
Clojure class
PDF
Clojure 1.1 And Beyond
KEY
Clojure Intro
PDF
Get into Functional Programming with Clojure
PDF
Functional (web) development with Clojure
PDF
I know Java, why should I consider Clojure?
PDF
'Getting' Clojure - '(parentheses are just hugs for your code)
PDF
Introductory Clojure Presentation
Progscon 2017: Taming the wild fronteer - Adventures in Clojurescript
ClojureScript - Making Front-End development Fun again - John Stevenson - Cod...
The Ideas of Clojure - Things I learn from Clojure
HelsinkiJS - Clojurescript for Javascript Developers
Functional web with clojure
Introduction to Clojure
A Taste of Clojure
Clojure 7-Languages
Clojure and The Robot Apocalypse
Getting started with Clojure
Clojure made-simple - John Stevenson
Why clojure(script) matters
Clojure class
Clojure 1.1 And Beyond
Clojure Intro
Get into Functional Programming with Clojure
Functional (web) development with Clojure
I know Java, why should I consider Clojure?
'Getting' Clojure - '(parentheses are just hugs for your code)
Introductory Clojure Presentation
Ad

Recently uploaded (20)

PDF
How to Choose the Right IT Partner for Your Business in Malaysia
PDF
Upgrade and Innovation Strategies for SAP ERP Customers
PDF
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
PPTX
Agentic AI Use Case- Contract Lifecycle Management (CLM).pptx
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
PPTX
VVF-Customer-Presentation2025-Ver1.9.pptx
PDF
How Creative Agencies Leverage Project Management Software.pdf
PDF
Softaken Excel to vCard Converter Software.pdf
PPTX
ai tools demonstartion for schools and inter college
PDF
Nekopoi APK 2025 free lastest update
PDF
Adobe Illustrator 28.6 Crack My Vision of Vector Design
PDF
Which alternative to Crystal Reports is best for small or large businesses.pdf
PDF
T3DD25 TYPO3 Content Blocks - Deep Dive by André Kraus
PDF
Understanding Forklifts - TECH EHS Solution
PPTX
CHAPTER 12 - CYBER SECURITY AND FUTURE SKILLS (1) (1).pptx
PDF
System and Network Administration Chapter 2
PPTX
Transform Your Business with a Software ERP System
PPTX
ManageIQ - Sprint 268 Review - Slide Deck
PPTX
Odoo POS Development Services by CandidRoot Solutions
PPTX
Online Work Permit System for Fast Permit Processing
How to Choose the Right IT Partner for Your Business in Malaysia
Upgrade and Innovation Strategies for SAP ERP Customers
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
Agentic AI Use Case- Contract Lifecycle Management (CLM).pptx
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
VVF-Customer-Presentation2025-Ver1.9.pptx
How Creative Agencies Leverage Project Management Software.pdf
Softaken Excel to vCard Converter Software.pdf
ai tools demonstartion for schools and inter college
Nekopoi APK 2025 free lastest update
Adobe Illustrator 28.6 Crack My Vision of Vector Design
Which alternative to Crystal Reports is best for small or large businesses.pdf
T3DD25 TYPO3 Content Blocks - Deep Dive by André Kraus
Understanding Forklifts - TECH EHS Solution
CHAPTER 12 - CYBER SECURITY AND FUTURE SKILLS (1) (1).pptx
System and Network Administration Chapter 2
Transform Your Business with a Software ERP System
ManageIQ - Sprint 268 Review - Slide Deck
Odoo POS Development Services by CandidRoot Solutions
Online Work Permit System for Fast Permit Processing

ClojureScript for the web