SlideShare a Scribd company logo
1 of 134
Download to read offline
Better Living Through
Clojure
MIT IAP
January 14-15, 2014
We are ….

Bhaskar (Buro) Mookerji
(‘09 VIII , ‘11 VI/MEng)

Aysylu Greenberg
(‘12 VI-2)

David Greenberg
(‘11 XVIII-C)
Today’s agenda includes...
●
●
●
●
●
●

Clojure Overview
Syntax: Everything is Data
Functions
Flow Control
Collections
Sequences
... and tomorrow:
●
●
●
●
●
●
●
●

Testing
Concurrency
Polymorphism
JVM Interop
Performance
Tooling
Interesting Problems Solved by Clojure
Our Projects
Clojure Overview
Rationale and Philosophy
● First released by Rich Hickey in 2007
○ Expressive functional programming with Lisp
○ Designed for concurrency use by default
○ Embedded in an existing platform

● Robust, practical, high-performance
● Simple abstractions backed by powerful
ideas
The familiar solutions are complex
● Complacency breeds incidental complexity
○ Large programs are difficult to understand
○ Scope of effects are difficult to reason about
○ Concurrency: holy crap.

● “Object-oriented programming is overrated”
Clojure is a Lisp
About the use of language: it is
impossible to sharpen a pencil with a
blunt axe. It is equally vain to try to do it
with ten blunt axes instead.
- Edsger Dijkstra
How do we tell truths that might hurt?, EWD498

(Actually John McCarthy.)
Clojure is a Lisp
● LISP: code=data, few primitives, abstraction
○ Local maximum in the hierarchy of expression

● Dynamically typed and compiled, interpreted
● Syntactic abstraction through macros
● Clojure:
○ Extends code-as-data to new data structures
○ Modernizes LISP with new ideas from existing
functional languages
Clojure is Functional and Dynamic
● Functions are first-class
● All data structures are immutable, persistent,
recursive, and support heterogeneous types
● Well-defined concurrent behavior
● Strict typing (i.e., Haskell, OCaml) is not
everyone nor needed for every application
Clojure Runs on the JVM (and Javascript!)
● OS independent
● JVM: Well-supported, existing platform, lots
of libraries/platforms
● Static types and safety
● Garbage collection and a great compiler
● Clojurescript:
○ Javascript as the platform: runs everywhere
Syntax:
Everything is Data
Atomic Literals
22

;; Long

“derp”

;; String

12345678901

;; BigInt

d e r p

;; Character

1.34

;; Double

#”[0-9]+”

;; Regex

1.34M

;; BigDecimal

:derp, ::derp

;; Keyword

22/3

;; Ratio

nil

;; null

true

;; boolean
Atomic Literals
22

;; Long

“derp”

;; String

12345678901

;; BigInt

d e r p

;; Character

1.34

;; Double

#”[0-9]+”

;; Regex

1.34M

;; BigDecimal

:derp, ::derp

;; Keyword

22/2

;; Ratio

nil

;; null

true

;; boolean

Evaluating literals in the REPL:
user=> 22
22
user=>

;;
;;
;;
;;

Read
Eval
Print
Loop
Atomic Literals
22

;; Long

“derp”

;; String

12345678901

;; BigInt

d e r p

;; Character

1.34

;; Double

#”[0-9]+”

;; Regex

1.34M

;; BigDecimal

:derp, ::derp

;; Keyword

22/2

;; Ratio

nil

;; null

true

;; boolean

Evaluating expressions:
user=> (+ 2 2)
4
user=>

;;
;;
;;
;;

Read
Eval
Print
Loop
Atomic Literals
22

;; Long

“derp”

;; String

12345678901

;; BigInt

d e r p

;; Character

1.34

;; Double

#”[0-9]+”

;; Regex

1.34M

;; BigDecimal

:derp, ::derp

;; Keyword

22/2

;; Ratio

nil

;; null

true

;; boolean

Evaluating expressions:
user=> ::derp
:user/derp
user=>

;;
;;
;;
;;

Read
Eval
Print
Loop
Atomic Literals
22

;; Long

“derp”

;; String

12345678901

;; BigInt

d e r p

;; Character

1.34

;; Double

#”[0-9]+”

;; Regex

1.34M

;; BigDecimal

:derp, ::derp

;; Keyword

22/2

;; Ratio

nil

;; null

true

;; boolean

Evaluating expressions:
user=> (class ::derp)
clojure.lang.Keyword
user=>
def binds names
user=> pi
;; NOOOOO!! ⇒ Undefined.
CompilerException java.lang.RuntimeException: ...
user=> (def pi 3.1415926)
#'user/pi
user=> pi
3.1415926
user=> (println pi)
3.1415926
nil
Data Structures
● Lists - singly-linked, front-append
○ (1 2 3 4)

● Vectors - indexed, back-append
○ [:a 2 3 “4”]

● Maps - key/value store
○ {:a 2 :b 4}

● Sets
○ #{:a :b :c :d}
Expressions are Data

From: http://alandipert.github.io/oscon2012-clojure/
Expressions are Data

vs…
From: http://alandipert.github.io/oscon2012-clojure/
Expressions are Data
(op ...)
● op can be a ….
○
○
○
○
○

Function: +, mod, println
Macro: when, cond, and
Special Operator: do, if, ref
Higher-order function
… anything callable (clojure.lang.IFn)
Function calls use parens...
user=> (defn hello [] "Hi!!!") ;; define hello function
user=> hello
;; return it
#<user$hello user$hello@be1a6e>
user=> (hello)
;; invoke it
"Hi!!!"

… but values never do
user=> (def my-name "Kelly Q. Programmer")
#'user/my-name
user=> my-name
"Kelly Q. Programmer"
user=>(my-name)
ClassCastException java.lang.String cannot be cast to clojure.
lang.IFn
Quote makes “variables” symbolic
user=> (def x 3)
#'user/x
user=> (+ x 2)
5
user=> '(+ x 2)
(+ x 2)

;; quoted list
;; returns list, unevaluated

user=> (quote (+ x 2))
(+ x 2)

;; same as above
Introspect your Environments
user=> (use 'clojure.repl) ;; Quoted symbol
user=> (doc if)
;; Print docstring
------------------------if
(if test then else?)
Special Form
Evaluates test. If not the singular values nil or false,
evaluates and yields then, otherwise, evaluates and yields
else. If
else is not supplied it defaults to nil.
Please see http://clojure.org/special_forms#if
nil
Introspect your Environments
user=> (source when)
(defmacro when
"Evaluates test. If logical true, evaluates body in an
implicit do."
{:added "1.0"}
[test & body]
(list 'if test (cons 'do body)))
nil
For More:
●

find-doc - Print docstring for var whose doc or name matches a pattern

●

apropos - returns a seq of definitions matching a regex

●

pst - print stack trace for a given exception or *e by default

●

See: http://clojure.org/cheatsheet
Namespaces are all around you
● Namespaces disambiguate names
○

vars -> symbols, functions, macros, Java class etc.
are all defined in namespaces

● Namespace management is a big part of
Clojure development
(ns com.your.great.app
(:require clojure.string
[clojure.set :as set]
[clojure.java.io :refer (file reader)]))
Functions
Functional Abstractions are Useful
● Clojure is functional
● Functions and higher-order functions are
generic in a obviously fundamental ways
● clojure.core (mostly) free of side-effects
● TBDL: Immutability and persistence
guarantee behavior and performance
defn binds functions
(defn messenger
;;
([]
;;
(messenger "Hi!"))
;;
([msg]
;;
(println msg))
;;
([msg & args]
;;
(println msg args)))
;;
user=> (messenger)
Hi!
user=> (messenger "Hi class!")
Hi class!
user=> (messenger "Hi class!" "Who?"
Hello class! (Who? What?)

multi-arity definition
no args
call self with default
one arg
print it
variadic definition
apply print to all args

"What?")
fn creates anonymous functions
● fn creates lambdas
(fn
( (fn
Hi!
nil

[message]

(println message) )

[message]

(println message) ) “Hi!”)
apply applies functions
● Invokes argument on arguments (last is a
sequence).
;; & puts rest of args into sequence
;; apply pulls args out of sequence
(defn messenger [greeting & who]
(apply println greeting who))
user=> (messenger "Hi, everyone!" "Who?" "What?")
Hi, everyone! Who? What?
let binds symbols to values
● Values are either literal or expressions
● Bound symbols have “lexical scope”
(defn messenger [msg]
(let [a “Who?”
b “What?”
c (capitalize msg)]
(println a b c)))
user=> (messenger “Why?”)
Who? What? Why?
Closures
● Allows bindings to persist beyond the lexical
scope
(defn messenger-builder [greeting]
(fn [who] (println greeting who)))

;; defines closure

;; greeting provided here, then goes out of scope
(def hello-er (messenger-builder "Hello"))
;; greeting still available because hello-er is closure
user=> (hello-er "world!")
Hello world!
Flow Control
Expressions in Clojure
● Java, etc. : Expressions
return values, but
statements do not.

● Clojure: Everything is an
expression (-> value or
nil)

String s;

(if (= s “foo”) “bar”)

if (s == “foo”) {
s = “bar”;
}
return s;

(do (stuff)

;; Do stuff.

(= s “foo”) ;; => true
Flow Control Operators
● if, when, if-not, when-not, do, cond,
case, etc. are all flow control operators.
● composable and general
“Truthiness”
(if
(if
(if
(if

true :truthy :falsey)
(Object.) :truthy :falsey)
[] :truthy :falsey)
0 :truthy :falsey)

;;=> :truthy, and so are:
;; objects
;; empty collections
;; zero

(if false :truthy :falsey)
(if nil :truthy :falsey)
(if (seq []) :truthy :falsey)

;;=> :falsey
;; nil
;; seq on empty collection

(and true 0 22)

;; returns last expression

(or true false 22)
if, do, and when
user => (if (even? 5)
;; if is multibranch
(do (println "Even!") ;; do evaluates block and
true)
;; returns last value
(do (println "Odd!")
false))
odd
;; printed
false
;; return value
user => (when (even? 5)
(println "Even!")
true)

;; when is single-branch
;; sugar for (if <>(do..))
cond and case
(let [x 22]
;; Compares predicates
(cond
(<= x 22) "Dismissed as coincidence."
(> x 222) "x is greater than 222."
:else
"No conditions met"))
(defn bazbar [x]
(case x
22 "x is 22"
222 "x is 222"
"x is neither 22 or 222"))

;; Matches arguments
;; in O(1) time
;; Must be literals
Iterations (and side effects)
(dotimes [i 5]
(println i))

;; Evals and returns nil.

(doseq [letter [:a :b :c]
;; Imperative cartesian product.
number (range 5)]
(println [letter number]))
(for [letter [:a :b :c]
number (range 5)]
[letter number])

;; Sequence cartesian product.
;; ([:a 0] [:a 1] [:a 2] [:b 0]
;; [:b 1] [:b 2] …)
Threading Macros Remove Nesting
;; Deeply-nested parens ...
(first (.split (.replace (.toUpperCase "a b c d") "A" "X")
" "))
;; ...

are unwinded with thread-first macro

(-> "a b c d"
.toUpperCase
(.replace "A" "X")
(.split " ")
first)
;; Also ->>, as->, cond->, cond->>, etc.
Recursion (with loop/recur)
● loop binds, recur re-loops
● Strong prefer iteration and higher-order
functions over recursion
(loop [i 0]
(if (< i 22)
(recur (inc i))
i))
22
Today ….
●
●
●
●
●
●

Intro to Clojure
Clojure Overview & REPL
Functions
Flow Control
Collections
Sequences
Collections
● Extensive facilities for representing and
manipulating data
● Small number of data structures
● Seq abstraction common across data
structures
● Large library of functions across all of them
Collections: Immutability
● Simple (numbers, strings) and compound
values are immutable
● Key to Clojure's concurrency model
● Cannot change immutable values
○ Generate new ones instead
○ Persistent data structures for efficiency
Collections: Persistent Data
Structures
● New values = old values + modifications
● New values are not full copies
● New value and old value are both available
after 'changes'
● Performance guarantees for most operations
● All Clojure data structures are persistent
Collections: Persistent Data
Structures

http://eclipsesource.com/blogs/2009/12/13/persistent-trees-in-git-clojure-and-couchdb-data-structureconvergence/
Collections: Data Structures
● Sequential: list
Collections: Data Structures
● Sequential: list
○
○
○
○

Singly-linked lists
Prepend: O(1)
Lookup: O(1) at head, O(n) anywhere else
Grow at the head (front)
Collections: Data Structures
● Sequential: list
()

;=> the empty list

(:a :b :c)

; error because :a not function

'(:a :b :c)

;=> (:a :b :c)

(list :a :b :c)

;=> (:a :b :c)

(conj '(:b :c) :a) ;=> (:a :b :c)
Collections: Data Structures
● Sequential: list, vector
Collections: Data Structures
● Sequential: list, vector
○
○
○
○

Indexed, random-access, array-like
Append: O(1) *
Lookup: O(1) *
Grow at the tail (end)

O(1) * = O(log 32 n), really close to O(1),
is O(1) for n < 1 billion
Collections: Data Structures
● Sequential: list, vector
[]
;=> the empty vector
[:a :b :c]
;=> [:a :b :c]
(vector :a :b :c) ;=> [:a :b :c]
(vec '(:a :b :c)) ;=> [:a :b :c]
(nth [:a :b :c] 0) ;=> :a
(conj [:a :b] :c) ;=> [:a :b :c]
Collections: Data Structures
● Sequential: list, vector
● Associative: map
Collections: Data Structures
● Sequential: list, vector
● Associative: map
○ Key → value, hash table, dictionary
○ Insert and lookup: O(1) *
○ Unordered
Collections: Data Structures
● Sequential: list, vector
● Associative: map
{}
{:a "a" :b "b"}
(get {:a "a"} :a)
(get {:a "a"} :z)
(get {:a "a"} :z 22)

;;=> the empty map
;;=> {:a "a" :b "b"}
;;=> "a"
;;=> nil ; not found
;;=> 22
; default

(assoc {:a "a"} :b "b") ;;=> {:a "a" :b "b"}
(dissoc {:a "a"} :a)
;;=> {}
(conj {} [:a "a"])
;;=> {:a "a"}
Collections: Data Structures
● Sequential: list, vector
● Associative: map
○ Nested access: get-in, assoc-in, update-in
(def our-class {:class "Better Living Through Clojure"
:location {:room "4-231"})
Collections: Data Structures
● Sequential: list, vector
● Associative: map
○ Nested access: get-in, assoc-in, update-in
(def our-class {:class "Better Living Through Clojure"
:location {:room "4-231"})
(get (get our-class :location) :room) ;;=> "4-231"
Collections: Data Structures
● Sequential: list, vector
● Associative: map
○ Nested access: get-in, assoc-in, update-in
(def our-class {:class "Better Living Through Clojure"
:location {:room "4-231"})
(get (get our-class :location) :room) ;;=> "4-231"
(-> our-class
(get :location)
(get :room))
;;=> "4-231"
Collections: Data Structures
● Sequential: list, vector
● Associative: map
○ Nested access: get-in, assoc-in, update-in
(def our-class {:class "Better Living Through Clojure"
:location {:room "4-231"})
(get (get our-class :location) :room) ;;=> "4-231"
(-> our-class
(get :location)
(get :room))
;;=> "4-231"
(get-in our-class [:location :room]) ;;=> "4-231"
Collections: Data Structures
● Sequential: list, vector
● Associative: map, set
Collections: Data Structures
● Sequential: list, vector
● Associative: map, set
○
○
○
○

Set of distinct values
Insert: O(1) *
Member?: O(1) *
Unordered
Collections: Data Structures
● Sequential: list, vector
● Associative: map, set
#{}
#{"a" "b"}

;;=> the empty set
;;=> #{"a" "b"}

(set ["a" "b"])

;;=> #{"a" "b"}

(conj #{} "a")

;;=> #{"a"}

(contains? #{"a"} "a") ;;=> true
Collections: Data Structures are
Functions
● Maps are functions of their keys
(def dict {:a "a" :b "b"})
(dict :b)
;;=> "b"
Collections: Data Structures are
Functions
● Maps are functions of their keys
(def dict {:a "a" :b "b"})
(dict :b)
;;=> "b"

● Keywords are functions of maps
(:b dict)

;;=> "b"
Collections: Data Structures are
Functions
● Maps are functions of their keys
(def dict {:a "a" :b "b"})
(dict :b)
;;=> "b"

● Keywords are functions of maps
(:b dict)

;;=> "b"

● Sets are functions of their elements
(def s #{3 7 9})
(s 7)
;;=> 7
Collections: Data Structures are
Functions
● Maps are functions of their keys
(def dict {:a "a" :b "b"})
(dict :b) ;;=> "b"

● Keywords are functions of maps
(:b dict)

;;=> "b"

● Sets are functions of their elements
(def s #{3 7 9})
(s 7)
;;=> 7

● Vectors are functions of their indices
(def v [:a :b :c])
(v 1)
;;=> :b
Collections: Destructuring
● Declarative way to pull apart compound data
○ vs. explicit, verbose access

● Sequential & associative data structures
● Nests for deep, arbitrary access
● Works in fn and defn params, let bindings
Collections: Destructuring
;; Without destructuring:
(defn next-fib-pair [pair]
[(second pair) (+ (first pair) (second pair))])
Collections: Destructuring
;; Without destructuring:
(defn next-fib-pair [pair]
[(second pair) (+ (first pair) (second pair))])
;; With destructuring:
(defn next-fib-pair [[x y]]
[y (+ x y)])
Today ….
●
●
●
●
●
●
●

Intro to Clojure
Clojure Overview & REPL
Functions
Flow Control
Names & Namespaces
Collections
Sequences
Sequences
● Abstraction for representing iteration
● Backed by a data structure or a function
○ Can be lazy and/or "infinite"

● Foundation for large library of functions
Sequences: API
● (seq coll)
○ If collection is not empty, return seq object on it
○ If collection is empty, return nil
Sequences: API
● (seq coll)
○ If collection is not empty, return seq object on it
○ If collection is empty, return nil

● (first coll) returns the first element
Sequences: API
● (seq coll)
○ If collection is not empty, return seq object on it
○ If collection is empty, return nil

● (first coll) returns the first element
● (rest coll) returns a sequence of the rest of
the elements
Sequences: API
● (seq coll)
○ If collection is not empty, return seq object on it
○ If collection is empty, return nil

● (first coll) returns the first element
● (rest coll) returns a sequence of the rest of
the elements
● (cons x coll) returns a new sequence: first is
x, rest is coll
Sequences: Example
(seq [1 2 3])

;=> (1 2 3) ; not a list

(seq "Clojure")

;=> (C l o j u r e)

(seq {:a 1 :b 2})

;=> ([:a 1] [:b 2]) ; seq of map entries

(seq a-java-array) ;=> (...)
(seq [])
(seq "")
(seq {})

;=> nil
;=> nil
;=> nil
Sequences: Over Structures
● We can treat any data structure as a seq
(def s '(1 2 3))

; s is a list

s

1

2

3
Sequences: Over Structures
● We can treat any data structure as a seq
(def s '(1 2 3))
(def a (first s))

; s is a list
; a is 1

s

a

1

2

3
Sequences: Over Structures
● We can treat any data structure as a seq
(def s '(1 2 3)) ; s is a list
(def r (rest s)) ; r is a seq

s

r

1

2

3
Sequences: Over Structures
● We can treat any data structure as a seq
(def s '(1 2 3))
; s is a list
(def b (first (rest s)) ; b is 2
(def b (second s))
; same thing
s

1

b

2

3
Sequences: Over Structures
● We can treat any data structure as a seq
○ Lists are seqs
○ Others are wrapped
○ Associative structures become sequence of pairs
Sequences: Over Functions
● Can map a generator function to a seq
● Seq is lazy, can be infinite
● Can process more than fits in memory
(def
(def
(def
(def
(def
(def
(def

r (range 1 100))
; r is a lazy seq
a (first r))
; a is 1
s (rest r))
; s is a lazy seq
b (first (rest r))
; b is 2
b (second r))
; same thing
c (first (rest (rest r)))) ; c is 3
c (nth r 2))
; same thing
Sequences: Generation
(range)

;=> (0 1 2 ... infinite

(range 5)

;=> (0 1 2 3 4)

(repeat :b)

;=> (:b :b :b ... infinite

(repeatedly #(rand-int 100))

;=> (89 58 73 ... infinite
Sequences: Into Collections
(into #{} "hello")

;=> #{e h l o}

(into {} [[:x 1] [:y 2]]) ;=> {:x 1, :y 2}
(into () [:a :b :c])

;=> (:c :b :a)
Sequences: Shorten
(take 3 (range)) ;=> (0 1 2)
(drop 3 (range)) ;=> (3 4 5 ... infinite
(filter even? (range)) ;=> (0 2 4 6 ... infinite
(remove even? (range)) ;=> (1 3 5 7 ... infinite
Sequences: Lengthen
(concat [:a :b] (range 2 5))
(cycle [:a :b :c])
(interpose , (range 3))

;=> (:a :b 2 3 4)

;=> (:a :b :c :a :b ... infinite
;=> (0 , 1 , 2)
Sequences: map
(map even? (range 1 5))

;=> (false true false true)

(map + [1 2 3] [4 5 6]) ;=> (5 7 9)
(map * [1 2 3] (range 1000)) ;=> (0 2 6)
Sequences: reduce
(reduce function init seq)
●
●
●
●

function takes 2 arguments: accumulator and the current argument
reduce calls (function init (first seq))
Return value becomes init for next step
Repeat until the end of the seq, returns the last init

(reduce (fn [total item] (+ total (* 10 item)))
0 ; init
[1 2 3 4]) ;=> 100
Sequences: some
(some even? [1 2 3 4]) ;=> true
(some #{:foo} [:baz :bar :foo]) ;=> :foo
Combine sequence functions: Power
;; Sum of the first 50 odd integers
(reduce + (take 50 (filter odd? (range)))) ;=> 2500
;; Top 5 most frequently used words in the docstrings of the current namespace
(->> (ns-publics *ns*)
(map (comp :doc meta val))
(remove nil?)
(mapcat (fn [s] (re-seq #"w+" s)))
(frequencies)
(sort-by val)
(reverse)
(take 5)
(map first))
In this Class
●
●
●
●
●
●
●
●

Testing
Concurrency
Polymorphism
JVM Interop
Performance
Tooling
Interesting Problems Solved by Clojure
Our Projects
clojure.test
(deftest math-basics
(is (= 3 (+ 1 2)))
(is (= 10 (* 2 5)))
(is (thrown? java.lang.ArithmeticException (/ 1 0))))
midje
(fact
(+ 1 2) => 3
(* 2 5) => 10
(/ 1 0) => (throws java.lang.ArithmeticException))
expectations
(expect 3 (+ 1 2))
(expect 10 (* 2 5))
(expect java.lang.ArithmeticException (/ 1 0))
In this Class
●
●
●
●
●
●
●
●

Testing
Concurrency
Polymorphism
JVM Interop
Performance
Tooling
Interesting Problems Solved by Clojure
Our Projects
Benefits of Immutability
● What is a race
condition?
● How does
immutability
help?
Atoms
;; Create atom with initial value
(def a (atom 0))
;; Atomically transition from old to new value
(swap! a (fn [old-value] (+ 3 old-value)))
;; Set to a new value, regardless of old value
(reset! a 22)
Refs and Agents
● Refs allow you do many “swap!”s
transactionally
○ aka Software Transactional Memory

● Agents allow you do do “swap!”s
asynchronously on a thread pool
○ a dual of actors: send functions to the value, rather
than values (messages) to the function (actor)
core.async
● Go-style communicating sequential
processes
● “select” operator
● Scalable user-space scheduling
● Works in ClojureScript
● See the talk from Clojure Conj here
In this Class
●
●
●
●
●
●
●
●

Testing
Concurrency
Polymorphism
JVM Interop
Performance
Tooling
Interesting Problems Solved by Clojure
Our Projects
Two kinds of polymorphism
Protocols

Multimethods

Dispatch

The first argument’s type

Arbitrary function of all arguments

Performance

Fast; uses native virtual dispatch

Slow; requires a hash table lookup

Popularity

Extremely popular, good reputation

Used only when arbitrary dispatch is
necessary
Protocols
● Solves the expression problem
○ “How can we extend existing functions to new
datatypes and new functions to existing datatypes
without recompiling all code?”

● Uses perfect hashing and Java interfaces for
dispatching
Protocols - Example
(defprotocol ITaskRunner
(run [this task] "run the task, which is a fn"))
(defrecord ThreadRunner [name]
ITaskRunner
(run [this task] (future (task)))
(defrecord ImmediateRunner [nickname]
ITaskRunner
(run [this task] (task)))
(run (->ThreadRunner "Bob") (fn [] (println "hello world from thread")))
(run (->ImmediateRunner "Lily") (fn [] (println "hello world from stack")))
Protocols - Example
(defprotocol INamed
(named [this] "Return the name of this"))
(extend-protocol INamed
TaskRunner
(named [this] (:name this))
ImmediateRunner
(named [this] (:nickname this)))
(named (->ThreadRunner "Bob"))
;;=> "Bob"
(named (->ImmediateRunner "Lily"))
;;=> "Lily"
Multimethods - Example
;; We define a multimethod with its dispatch function
(defmulti battle
"Engage 2 spacecraft in epic battle"
(fn [x y] [(:type x) (:type y)]))
;; We can even create hierarchies of keywords.
;; Java types are permissible as leaves
(derive :x-wing :ship)
Multimethods - Example
;; We can define arbitrary numbers of implementations
(defmethod battle [:death-star :planet]
[death-star planet]
(str planet " has been obliterated by " death-star))
(defmethod battle [:ship :star-destroyer]
[ship destroyer]
(str ship " has been eliminated by " destroyer "defenses"))
(defmethod battle [:x-wing :death-star]
[x-wing death-star]
(str x-wing " perfectly shot its proton torpedoes into " death-star))
In this Class
●
●
●
●
●
●
●
●

Testing
Concurrency
Polymorphism
JVM Interop
Performance
Tooling
Interesting Problems Solved by Clojure
Our Projects
Exceptions
(try
(do-something-that-could-fail)
(catch RuntimeException e
(print-stack-trace e))
(finally
(dispose-of-resources)))
Making your own Exceptions
(try
(throw (ex-info "A data-carrying exception"
{:x 22 :y 42}))
(catch clojure.lang.ExceptionInfo e
(println ":x is" (:x (ex-data e)))))
Java Interop
Task

Java

Clojure

Instantiation

new MyClass(“foo”)

(MyClass. “foo”)

Instance method

dog.bark()

(.bark dog)

Instance field

object.field

(.-field object)

Static method

Math.sin(22)

(Math/sin 22)

Static field

Math.PI

Math/PI
Java Methods vs. Clojure Functions
;; Works
(map str (range 10))
;; Doesn’t work
(map .toString (range 10))
;;Works
(map (fn [x] (.toString x)) (range 10))
Clojure Types are Java Types
Clojure Type

Java Type

Long

java.lang.Long

Double

java.lang.Double

Boolean

java.lang.Boolean

String

java.lang.String

Regex

java.util.regex.Pattern

BigDecimal

java.lang.BigDecimal

BigInt

clojure.lang.BigInt (wraps java.lang.BigInteger or long)
Clojure Types are Java Types
Clojure Type

Java Type

Function

java.lang.Runnable, java.util.concurrent.Callable

List

java.util.List *

Vector

java.util.List *

Map

java.util.Map *

Set

java.util.Set *

* Does not include mutation operators, like add() or put()
In this Class
●
●
●
●
●
●
●
●

Testing
Concurrency
Polymorphism
JVM Interop
Performance
Tooling
Interesting Problems Solved by Clojure
Our Projects
How long did it take?
;;Built-in (simple)
(time (dotimes [i 1000] (+ 1 1)))
;;Criterium (statistically robust)
(criterium.core/bench (+ 1 1))
Clojurians care about Speed
●
●
●
●
●

Transient collections
Protocols
Unboxed numeric support in the compiler
no.dissassemble (inspect bytecode of fn)
Performance-oriented libraries
○ core.async - user space threading
○ core.matrix - matrix math
○ narrator - time series analysis
What’s in your toolkit?
Complex

Simple

State, Objects, Methods

Values, Functions/Namespaces

Variables

Managed references and concurrency

Inheritance, switch, matching

Polymorphism

Syntax

Data

Imperative loops, folds

Sequence Functions

Conditionals

Rules

Inconsistency

Consistency and Design

“Paradigms”

Syntactic Abstraction
In this Class
●
●
●
●
●
●
●
●

Testing
Concurrency
Polymorphism
JVM Interop
Performance
Tooling
Interesting Problems Solved by Clojure
Our Projects
Leiningen
●

“for automating Clojure projects without setting your hair on fire”

●

Functional project management

●

Fetches dependencies and constructs classpath

●

Packages and deploys project

●

Easily extensible with plugins
Leingen - usage
lein
lein
lein
lein

new my-cool-project
repl
uberjar
deploy clojars

(defproject my-cool-project "0.1.0-SNAPSHOT"
...
:dependencies [[org.clojure/clojure "1.4.0"]
[ring "1.2.1"]])
Vim
● fireplace
○
○
○
○

Simple evaluation
Prefix intellisense
Documentation lookup
Go to source

● redl
○ Advanced REPL with simple debugger
○ Fuzzy intellisense
Emacs
● cider
○
○
○
○

Advanced REPL
Documentation lookup
Symbol completion
Source lookup

● ritz
○ Stepping debugger via JVM’s debugging API
○ All features of cider
Light Table
●
●
●
●

Easiest to get started
REPL
Inline documentation
Written in Clojure(Script)!
Paredit + Rainbow Parens
● It’s really hard to keep parens, braces, and
brackets matching
● It’s really hard to see which ones are pairs
● Let your editor handle it!
In this Class
●
●
●
●
●
●
●
●

Testing
Concurrency
Polymorphism
JVM Interop
Performance
Tooling
Interesting Problems Solved by Clojure
Our Projects
Clojure Toolbox
● clojure-toolbox.com
● Great starting point for projects!
● Database clients, web frameworks, data
structures, parsers, etc.
● Purely functional
database
● Horizontal read
scalability
Storm
● Hadoop for realtime data
● Used by Twitter to
process all tweets in
real-time (and by
many others!)
Riemann
● Event processor and monitoring tool for
distributed systems
● Makes it easy to monitor clusters, calculate
statistics, and send alerts
Instaparse
What if context-free grammars were as easy to
use as regular expressions?
(insta/parser
"S = AB*
AB = A B
A = 'a'+
B = 'b'+")
In this Class
●
●
●
●
●
●
●
●

Testing
Concurrency
Polymorphism
JVM Interop
Performance
Tooling
Interesting Problems Solved by Clojure
Our Projects
Sources
● http://clojure.org
● Talks by Rich Hickey: Clojure, Are We There
Yet, and Simple Made Easy
● Beating the Averages, Paul Graham

More Related Content

What's hot

Compact and safely: static DSL on Kotlin
Compact and safely: static DSL on KotlinCompact and safely: static DSL on Kotlin
Compact and safely: static DSL on KotlinDmitry Pranchuk
 
Python 2.5 reference card (2009)
Python 2.5 reference card (2009)Python 2.5 reference card (2009)
Python 2.5 reference card (2009)gekiaruj
 
The Logical Burrito - pattern matching, term rewriting and unification
The Logical Burrito - pattern matching, term rewriting and unificationThe Logical Burrito - pattern matching, term rewriting and unification
The Logical Burrito - pattern matching, term rewriting and unificationNorman Richards
 
4java Basic Syntax
4java Basic Syntax4java Basic Syntax
4java Basic SyntaxAdil Jafri
 
Rainer Grimm, “Functional Programming in C++11”
Rainer Grimm, “Functional Programming in C++11”Rainer Grimm, “Functional Programming in C++11”
Rainer Grimm, “Functional Programming in C++11”Platonov Sergey
 
Predictably
PredictablyPredictably
Predictablyztellman
 
Swift for TensorFlow - CoreML Personalization
Swift for TensorFlow - CoreML PersonalizationSwift for TensorFlow - CoreML Personalization
Swift for TensorFlow - CoreML PersonalizationJacopo Mangiavacchi
 
Coscup2021-rust-toturial
Coscup2021-rust-toturialCoscup2021-rust-toturial
Coscup2021-rust-toturialWayne Tsai
 
Coscup2021 - useful abstractions at rust and it's practical usage
Coscup2021 - useful abstractions at rust and it's practical usageCoscup2021 - useful abstractions at rust and it's practical usage
Coscup2021 - useful abstractions at rust and it's practical usageWayne Tsai
 
[2019-07] GraphQL in depth (serverside)
[2019-07] GraphQL in depth (serverside)[2019-07] GraphQL in depth (serverside)
[2019-07] GraphQL in depth (serverside)croquiscom
 
Cheat sheet python3
Cheat sheet python3Cheat sheet python3
Cheat sheet python3sxw2k
 
The Ring programming language version 1.7 book - Part 39 of 196
The Ring programming language version 1.7 book - Part 39 of 196The Ring programming language version 1.7 book - Part 39 of 196
The Ring programming language version 1.7 book - Part 39 of 196Mahmoud Samir Fayed
 
Python3 cheatsheet
Python3 cheatsheetPython3 cheatsheet
Python3 cheatsheetGil Cohen
 
Building a website in Haskell coming from Node.js
Building a website in Haskell coming from Node.jsBuilding a website in Haskell coming from Node.js
Building a website in Haskell coming from Node.jsNicolas Hery
 
Lecture07 the linked-list_as_a_data_structure_v3
Lecture07 the linked-list_as_a_data_structure_v3Lecture07 the linked-list_as_a_data_structure_v3
Lecture07 the linked-list_as_a_data_structure_v3Hariz Mustafa
 
Mementopython3 english
Mementopython3 englishMementopython3 english
Mementopython3 englishssuser442080
 
The Ring programming language version 1.6 book - Part 32 of 189
The Ring programming language version 1.6 book - Part 32 of 189The Ring programming language version 1.6 book - Part 32 of 189
The Ring programming language version 1.6 book - Part 32 of 189Mahmoud Samir Fayed
 

What's hot (20)

Compact and safely: static DSL on Kotlin
Compact and safely: static DSL on KotlinCompact and safely: static DSL on Kotlin
Compact and safely: static DSL on Kotlin
 
Pune Clojure Course Outline
Pune Clojure Course OutlinePune Clojure Course Outline
Pune Clojure Course Outline
 
Python 2.5 reference card (2009)
Python 2.5 reference card (2009)Python 2.5 reference card (2009)
Python 2.5 reference card (2009)
 
The Logical Burrito - pattern matching, term rewriting and unification
The Logical Burrito - pattern matching, term rewriting and unificationThe Logical Burrito - pattern matching, term rewriting and unification
The Logical Burrito - pattern matching, term rewriting and unification
 
Oop lecture9 13
Oop lecture9 13Oop lecture9 13
Oop lecture9 13
 
4java Basic Syntax
4java Basic Syntax4java Basic Syntax
4java Basic Syntax
 
Rainer Grimm, “Functional Programming in C++11”
Rainer Grimm, “Functional Programming in C++11”Rainer Grimm, “Functional Programming in C++11”
Rainer Grimm, “Functional Programming in C++11”
 
Predictably
PredictablyPredictably
Predictably
 
Swift for TensorFlow - CoreML Personalization
Swift for TensorFlow - CoreML PersonalizationSwift for TensorFlow - CoreML Personalization
Swift for TensorFlow - CoreML Personalization
 
Coscup2021-rust-toturial
Coscup2021-rust-toturialCoscup2021-rust-toturial
Coscup2021-rust-toturial
 
Coscup2021 - useful abstractions at rust and it's practical usage
Coscup2021 - useful abstractions at rust and it's practical usageCoscup2021 - useful abstractions at rust and it's practical usage
Coscup2021 - useful abstractions at rust and it's practical usage
 
[2019-07] GraphQL in depth (serverside)
[2019-07] GraphQL in depth (serverside)[2019-07] GraphQL in depth (serverside)
[2019-07] GraphQL in depth (serverside)
 
Cheat sheet python3
Cheat sheet python3Cheat sheet python3
Cheat sheet python3
 
The Ring programming language version 1.7 book - Part 39 of 196
The Ring programming language version 1.7 book - Part 39 of 196The Ring programming language version 1.7 book - Part 39 of 196
The Ring programming language version 1.7 book - Part 39 of 196
 
Python_ 3 CheatSheet
Python_ 3 CheatSheetPython_ 3 CheatSheet
Python_ 3 CheatSheet
 
Python3 cheatsheet
Python3 cheatsheetPython3 cheatsheet
Python3 cheatsheet
 
Building a website in Haskell coming from Node.js
Building a website in Haskell coming from Node.jsBuilding a website in Haskell coming from Node.js
Building a website in Haskell coming from Node.js
 
Lecture07 the linked-list_as_a_data_structure_v3
Lecture07 the linked-list_as_a_data_structure_v3Lecture07 the linked-list_as_a_data_structure_v3
Lecture07 the linked-list_as_a_data_structure_v3
 
Mementopython3 english
Mementopython3 englishMementopython3 english
Mementopython3 english
 
The Ring programming language version 1.6 book - Part 32 of 189
The Ring programming language version 1.6 book - Part 32 of 189The Ring programming language version 1.6 book - Part 32 of 189
The Ring programming language version 1.6 book - Part 32 of 189
 

Viewers also liked

Winning the Erlang Edit•Build•Test Cycle
Winning the Erlang Edit•Build•Test CycleWinning the Erlang Edit•Build•Test Cycle
Winning the Erlang Edit•Build•Test CycleRusty Klophaus
 
Clojure made-simple - John Stevenson
Clojure made-simple - John StevensonClojure made-simple - John Stevenson
Clojure made-simple - John StevensonJAX London
 
What can be done with Java, but should better be done with Erlang (@pavlobaron)
What can be done with Java, but should better be done with Erlang (@pavlobaron)What can be done with Java, but should better be done with Erlang (@pavlobaron)
What can be done with Java, but should better be done with Erlang (@pavlobaron)Pavlo Baron
 
20 reasons why we don't need architects (@pavlobaron)
20 reasons why we don't need architects (@pavlobaron)20 reasons why we don't need architects (@pavlobaron)
20 reasons why we don't need architects (@pavlobaron)Pavlo Baron
 
Messaging With Erlang And Jabber
Messaging With  Erlang And  JabberMessaging With  Erlang And  Jabber
Messaging With Erlang And Jabberl xf
 
Erlang - Because s**t Happens by Mahesh Paolini-Subramanya
Erlang - Because s**t Happens by Mahesh Paolini-SubramanyaErlang - Because s**t Happens by Mahesh Paolini-Subramanya
Erlang - Because s**t Happens by Mahesh Paolini-SubramanyaHakka Labs
 
VoltDB and Erlang - Tech planet 2012
VoltDB and Erlang - Tech planet 2012VoltDB and Erlang - Tech planet 2012
VoltDB and Erlang - Tech planet 2012Eonblast
 
NDC London 2014: Erlang Patterns Matching Business Needs
NDC London 2014: Erlang Patterns Matching Business NeedsNDC London 2014: Erlang Patterns Matching Business Needs
NDC London 2014: Erlang Patterns Matching Business NeedsTorben Hoffmann
 
Clojure: Functional Concurrency for the JVM (presented at Open Source Bridge)
Clojure: Functional Concurrency for the JVM (presented at Open Source Bridge)Clojure: Functional Concurrency for the JVM (presented at Open Source Bridge)
Clojure: Functional Concurrency for the JVM (presented at Open Source Bridge)Howard Lewis Ship
 
Elixir for aspiring Erlang developers
Elixir for aspiring Erlang developersElixir for aspiring Erlang developers
Elixir for aspiring Erlang developersTorben Dohrn
 
Clojure Intro
Clojure IntroClojure Intro
Clojure Introthnetos
 
Introduction to Erlang for Python Programmers
Introduction to Erlang for Python ProgrammersIntroduction to Erlang for Python Programmers
Introduction to Erlang for Python ProgrammersPython Ireland
 
Clojure: Towards The Essence of Programming
Clojure: Towards The Essence of ProgrammingClojure: Towards The Essence of Programming
Clojure: Towards The Essence of ProgrammingHoward Lewis Ship
 
Elixir Into Production
Elixir Into ProductionElixir Into Production
Elixir Into ProductionJamie Winsor
 
Clojure, Plain and Simple
Clojure, Plain and SimpleClojure, Plain and Simple
Clojure, Plain and SimpleBen Mabey
 

Viewers also liked (20)

Winning the Erlang Edit•Build•Test Cycle
Winning the Erlang Edit•Build•Test CycleWinning the Erlang Edit•Build•Test Cycle
Winning the Erlang Edit•Build•Test Cycle
 
Clojure made-simple - John Stevenson
Clojure made-simple - John StevensonClojure made-simple - John Stevenson
Clojure made-simple - John Stevenson
 
What can be done with Java, but should better be done with Erlang (@pavlobaron)
What can be done with Java, but should better be done with Erlang (@pavlobaron)What can be done with Java, but should better be done with Erlang (@pavlobaron)
What can be done with Java, but should better be done with Erlang (@pavlobaron)
 
20 reasons why we don't need architects (@pavlobaron)
20 reasons why we don't need architects (@pavlobaron)20 reasons why we don't need architects (@pavlobaron)
20 reasons why we don't need architects (@pavlobaron)
 
Clojure values
Clojure valuesClojure values
Clojure values
 
High Performance Erlang
High  Performance  ErlangHigh  Performance  Erlang
High Performance Erlang
 
Messaging With Erlang And Jabber
Messaging With  Erlang And  JabberMessaging With  Erlang And  Jabber
Messaging With Erlang And Jabber
 
Erlang - Because s**t Happens by Mahesh Paolini-Subramanya
Erlang - Because s**t Happens by Mahesh Paolini-SubramanyaErlang - Because s**t Happens by Mahesh Paolini-Subramanya
Erlang - Because s**t Happens by Mahesh Paolini-Subramanya
 
Elixir talk
Elixir talkElixir talk
Elixir talk
 
VoltDB and Erlang - Tech planet 2012
VoltDB and Erlang - Tech planet 2012VoltDB and Erlang - Tech planet 2012
VoltDB and Erlang - Tech planet 2012
 
NDC London 2014: Erlang Patterns Matching Business Needs
NDC London 2014: Erlang Patterns Matching Business NeedsNDC London 2014: Erlang Patterns Matching Business Needs
NDC London 2014: Erlang Patterns Matching Business Needs
 
From Perl To Elixir
From Perl To ElixirFrom Perl To Elixir
From Perl To Elixir
 
Clojure: Functional Concurrency for the JVM (presented at Open Source Bridge)
Clojure: Functional Concurrency for the JVM (presented at Open Source Bridge)Clojure: Functional Concurrency for the JVM (presented at Open Source Bridge)
Clojure: Functional Concurrency for the JVM (presented at Open Source Bridge)
 
Elixir for aspiring Erlang developers
Elixir for aspiring Erlang developersElixir for aspiring Erlang developers
Elixir for aspiring Erlang developers
 
Clojure Intro
Clojure IntroClojure Intro
Clojure Intro
 
Introduction to Erlang for Python Programmers
Introduction to Erlang for Python ProgrammersIntroduction to Erlang for Python Programmers
Introduction to Erlang for Python Programmers
 
Clojure: Towards The Essence of Programming
Clojure: Towards The Essence of ProgrammingClojure: Towards The Essence of Programming
Clojure: Towards The Essence of Programming
 
Elixir Into Production
Elixir Into ProductionElixir Into Production
Elixir Into Production
 
Clojure, Plain and Simple
Clojure, Plain and SimpleClojure, Plain and Simple
Clojure, Plain and Simple
 
Erlang - Because S**t Happens
Erlang - Because S**t HappensErlang - Because S**t Happens
Erlang - Because S**t Happens
 

Similar to Clojure class

Exploring Clojurescript
Exploring ClojurescriptExploring Clojurescript
Exploring ClojurescriptLuke Donnet
 
Knowledge of Javascript
Knowledge of JavascriptKnowledge of Javascript
Knowledge of JavascriptSamuel Abraham
 
Introduction to clojure
Introduction to clojureIntroduction to clojure
Introduction to clojureAbbas Raza
 
GDSC Flutter Forward Workshop.pptx
GDSC Flutter Forward Workshop.pptxGDSC Flutter Forward Workshop.pptx
GDSC Flutter Forward Workshop.pptxGDSCVJTI
 
Ceylon - the language and its tools
Ceylon - the language and its toolsCeylon - the language and its tools
Ceylon - the language and its toolsMax Andersen
 
JavaScript: The Good Parts Or: How A C# Developer Learned To Stop Worrying An...
JavaScript: The Good Parts Or: How A C# Developer Learned To Stop Worrying An...JavaScript: The Good Parts Or: How A C# Developer Learned To Stop Worrying An...
JavaScript: The Good Parts Or: How A C# Developer Learned To Stop Worrying An...Doug Jones
 
Functional Programming 101 for Java 7 Developers
Functional Programming 101 for Java 7 DevelopersFunctional Programming 101 for Java 7 Developers
Functional Programming 101 for Java 7 DevelopersJayaram Sankaranarayanan
 
Kotlin - The Swiss army knife of programming languages - Visma Mobile Meet-up...
Kotlin - The Swiss army knife of programming languages - Visma Mobile Meet-up...Kotlin - The Swiss army knife of programming languages - Visma Mobile Meet-up...
Kotlin - The Swiss army knife of programming languages - Visma Mobile Meet-up...Tudor Dragan
 
HTML5 for the Silverlight Guy
HTML5 for the Silverlight GuyHTML5 for the Silverlight Guy
HTML5 for the Silverlight GuyDavid Padbury
 
ClojureScript loves React, DomCode May 26 2015
ClojureScript loves React, DomCode May 26 2015ClojureScript loves React, DomCode May 26 2015
ClojureScript loves React, DomCode May 26 2015Michiel Borkent
 
Clojure - A new Lisp
Clojure - A new LispClojure - A new Lisp
Clojure - A new Lispelliando dias
 
JavaScript Essentials in 1 Hour (2018)
JavaScript Essentials in 1 Hour (2018)JavaScript Essentials in 1 Hour (2018)
JavaScript Essentials in 1 Hour (2018)Ahmed Ibrahim
 
Carlo Sciolla - Above and beyond type systems with clojure.spec - Codemotion ...
Carlo Sciolla - Above and beyond type systems with clojure.spec - Codemotion ...Carlo Sciolla - Above and beyond type systems with clojure.spec - Codemotion ...
Carlo Sciolla - Above and beyond type systems with clojure.spec - Codemotion ...Codemotion
 
Groovy On Trading Desk (2010)
Groovy On Trading Desk (2010)Groovy On Trading Desk (2010)
Groovy On Trading Desk (2010)Jonathan Felch
 

Similar to Clojure class (20)

Clojure Small Intro
Clojure Small IntroClojure Small Intro
Clojure Small Intro
 
Exploring Clojurescript
Exploring ClojurescriptExploring Clojurescript
Exploring Clojurescript
 
Knowledge of Javascript
Knowledge of JavascriptKnowledge of Javascript
Knowledge of Javascript
 
00_Introduction to Java.ppt
00_Introduction to Java.ppt00_Introduction to Java.ppt
00_Introduction to Java.ppt
 
Introduction to clojure
Introduction to clojureIntroduction to clojure
Introduction to clojure
 
GDSC Flutter Forward Workshop.pptx
GDSC Flutter Forward Workshop.pptxGDSC Flutter Forward Workshop.pptx
GDSC Flutter Forward Workshop.pptx
 
Ceylon - the language and its tools
Ceylon - the language and its toolsCeylon - the language and its tools
Ceylon - the language and its tools
 
JavaScript: The Good Parts Or: How A C# Developer Learned To Stop Worrying An...
JavaScript: The Good Parts Or: How A C# Developer Learned To Stop Worrying An...JavaScript: The Good Parts Or: How A C# Developer Learned To Stop Worrying An...
JavaScript: The Good Parts Or: How A C# Developer Learned To Stop Worrying An...
 
Clojure And Swing
Clojure And SwingClojure And Swing
Clojure And Swing
 
Functional Programming 101 for Java 7 Developers
Functional Programming 101 for Java 7 DevelopersFunctional Programming 101 for Java 7 Developers
Functional Programming 101 for Java 7 Developers
 
Meta Object Protocols
Meta Object ProtocolsMeta Object Protocols
Meta Object Protocols
 
PHP and MySQL
PHP and MySQLPHP and MySQL
PHP and MySQL
 
Kotlin - The Swiss army knife of programming languages - Visma Mobile Meet-up...
Kotlin - The Swiss army knife of programming languages - Visma Mobile Meet-up...Kotlin - The Swiss army knife of programming languages - Visma Mobile Meet-up...
Kotlin - The Swiss army knife of programming languages - Visma Mobile Meet-up...
 
HTML5 for the Silverlight Guy
HTML5 for the Silverlight GuyHTML5 for the Silverlight Guy
HTML5 for the Silverlight Guy
 
ClojureScript loves React, DomCode May 26 2015
ClojureScript loves React, DomCode May 26 2015ClojureScript loves React, DomCode May 26 2015
ClojureScript loves React, DomCode May 26 2015
 
Clojure - A new Lisp
Clojure - A new LispClojure - A new Lisp
Clojure - A new Lisp
 
JavaScript Essentials in 1 Hour (2018)
JavaScript Essentials in 1 Hour (2018)JavaScript Essentials in 1 Hour (2018)
JavaScript Essentials in 1 Hour (2018)
 
Carlo Sciolla - Above and beyond type systems with clojure.spec - Codemotion ...
Carlo Sciolla - Above and beyond type systems with clojure.spec - Codemotion ...Carlo Sciolla - Above and beyond type systems with clojure.spec - Codemotion ...
Carlo Sciolla - Above and beyond type systems with clojure.spec - Codemotion ...
 
Groovy On Trading Desk (2010)
Groovy On Trading Desk (2010)Groovy On Trading Desk (2010)
Groovy On Trading Desk (2010)
 
Groovy!
Groovy!Groovy!
Groovy!
 

More from Aysylu Greenberg

Software Supply Chains for DevOps @ InfoQ Live 2021
Software Supply Chains for DevOps @ InfoQ Live 2021Software Supply Chains for DevOps @ InfoQ Live 2021
Software Supply Chains for DevOps @ InfoQ Live 2021Aysylu Greenberg
 
Binary Authorization in Kubernetes
Binary Authorization in KubernetesBinary Authorization in Kubernetes
Binary Authorization in KubernetesAysylu Greenberg
 
Software Supply Chain Management with Grafeas and Kritis
Software Supply Chain Management with Grafeas and KritisSoftware Supply Chain Management with Grafeas and Kritis
Software Supply Chain Management with Grafeas and KritisAysylu Greenberg
 
Software Supply Chain Observability with Grafeas and Kritis
Software Supply Chain Observability with Grafeas and KritisSoftware Supply Chain Observability with Grafeas and Kritis
Software Supply Chain Observability with Grafeas and KritisAysylu Greenberg
 
Software Supply Chain Management with Grafeas and Kritis
Software Supply Chain Management with Grafeas and KritisSoftware Supply Chain Management with Grafeas and Kritis
Software Supply Chain Management with Grafeas and KritisAysylu Greenberg
 
Zero Downtime Migrations at Scale
Zero Downtime Migrations at ScaleZero Downtime Migrations at Scale
Zero Downtime Migrations at ScaleAysylu Greenberg
 
Distributed systems in practice, in theory (ScaleConf Colombia)
Distributed systems in practice, in theory (ScaleConf Colombia)Distributed systems in practice, in theory (ScaleConf Colombia)
Distributed systems in practice, in theory (ScaleConf Colombia)Aysylu Greenberg
 
MesosCon Asia Keynote: Replacing a Jet Engine Mid-flight
MesosCon Asia Keynote: Replacing a Jet Engine Mid-flightMesosCon Asia Keynote: Replacing a Jet Engine Mid-flight
MesosCon Asia Keynote: Replacing a Jet Engine Mid-flightAysylu Greenberg
 
Distributed systems in practice, in theory (JAX London)
Distributed systems in practice, in theory (JAX London)Distributed systems in practice, in theory (JAX London)
Distributed systems in practice, in theory (JAX London)Aysylu Greenberg
 
Building A Distributed Build System at Google Scale (StrangeLoop 2016)
Building A Distributed Build System at Google Scale (StrangeLoop 2016)Building A Distributed Build System at Google Scale (StrangeLoop 2016)
Building A Distributed Build System at Google Scale (StrangeLoop 2016)Aysylu Greenberg
 
QCon NYC: Distributed systems in practice, in theory
QCon NYC: Distributed systems in practice, in theoryQCon NYC: Distributed systems in practice, in theory
QCon NYC: Distributed systems in practice, in theoryAysylu Greenberg
 
Building a Distributed Build System at Google Scale
Building a Distributed Build System at Google ScaleBuilding a Distributed Build System at Google Scale
Building a Distributed Build System at Google ScaleAysylu Greenberg
 
Distributed systems in practice, in theory
Distributed systems in practice, in theoryDistributed systems in practice, in theory
Distributed systems in practice, in theoryAysylu Greenberg
 
Probabilistic Accuracy Bounds @ Papers We Love SF
Probabilistic Accuracy Bounds @ Papers We Love SFProbabilistic Accuracy Bounds @ Papers We Love SF
Probabilistic Accuracy Bounds @ Papers We Love SFAysylu Greenberg
 
Benchmarking (JAXLondon 2015)
Benchmarking (JAXLondon 2015)Benchmarking (JAXLondon 2015)
Benchmarking (JAXLondon 2015)Aysylu Greenberg
 
Loom & Functional Graphs in Clojure @ LambdaConf 2015
Loom & Functional Graphs in Clojure @ LambdaConf 2015Loom & Functional Graphs in Clojure @ LambdaConf 2015
Loom & Functional Graphs in Clojure @ LambdaConf 2015Aysylu Greenberg
 
Benchmarking (DevNexus 2015)
Benchmarking (DevNexus 2015)Benchmarking (DevNexus 2015)
Benchmarking (DevNexus 2015)Aysylu Greenberg
 

More from Aysylu Greenberg (20)

Software Supply Chains for DevOps @ InfoQ Live 2021
Software Supply Chains for DevOps @ InfoQ Live 2021Software Supply Chains for DevOps @ InfoQ Live 2021
Software Supply Chains for DevOps @ InfoQ Live 2021
 
Binary Authorization in Kubernetes
Binary Authorization in KubernetesBinary Authorization in Kubernetes
Binary Authorization in Kubernetes
 
Software Supply Chain Management with Grafeas and Kritis
Software Supply Chain Management with Grafeas and KritisSoftware Supply Chain Management with Grafeas and Kritis
Software Supply Chain Management with Grafeas and Kritis
 
Software Supply Chain Observability with Grafeas and Kritis
Software Supply Chain Observability with Grafeas and KritisSoftware Supply Chain Observability with Grafeas and Kritis
Software Supply Chain Observability with Grafeas and Kritis
 
Software Supply Chain Management with Grafeas and Kritis
Software Supply Chain Management with Grafeas and KritisSoftware Supply Chain Management with Grafeas and Kritis
Software Supply Chain Management with Grafeas and Kritis
 
Zero Downtime Migrations at Scale
Zero Downtime Migrations at ScaleZero Downtime Migrations at Scale
Zero Downtime Migrations at Scale
 
Zero Downtime Migration
Zero Downtime MigrationZero Downtime Migration
Zero Downtime Migration
 
PWL Denver: Copysets
PWL Denver: CopysetsPWL Denver: Copysets
PWL Denver: Copysets
 
Distributed systems in practice, in theory (ScaleConf Colombia)
Distributed systems in practice, in theory (ScaleConf Colombia)Distributed systems in practice, in theory (ScaleConf Colombia)
Distributed systems in practice, in theory (ScaleConf Colombia)
 
MesosCon Asia Keynote: Replacing a Jet Engine Mid-flight
MesosCon Asia Keynote: Replacing a Jet Engine Mid-flightMesosCon Asia Keynote: Replacing a Jet Engine Mid-flight
MesosCon Asia Keynote: Replacing a Jet Engine Mid-flight
 
Distributed systems in practice, in theory (JAX London)
Distributed systems in practice, in theory (JAX London)Distributed systems in practice, in theory (JAX London)
Distributed systems in practice, in theory (JAX London)
 
Building A Distributed Build System at Google Scale (StrangeLoop 2016)
Building A Distributed Build System at Google Scale (StrangeLoop 2016)Building A Distributed Build System at Google Scale (StrangeLoop 2016)
Building A Distributed Build System at Google Scale (StrangeLoop 2016)
 
QCon NYC: Distributed systems in practice, in theory
QCon NYC: Distributed systems in practice, in theoryQCon NYC: Distributed systems in practice, in theory
QCon NYC: Distributed systems in practice, in theory
 
Building a Distributed Build System at Google Scale
Building a Distributed Build System at Google ScaleBuilding a Distributed Build System at Google Scale
Building a Distributed Build System at Google Scale
 
(+ Loom (years 2))
(+ Loom (years 2))(+ Loom (years 2))
(+ Loom (years 2))
 
Distributed systems in practice, in theory
Distributed systems in practice, in theoryDistributed systems in practice, in theory
Distributed systems in practice, in theory
 
Probabilistic Accuracy Bounds @ Papers We Love SF
Probabilistic Accuracy Bounds @ Papers We Love SFProbabilistic Accuracy Bounds @ Papers We Love SF
Probabilistic Accuracy Bounds @ Papers We Love SF
 
Benchmarking (JAXLondon 2015)
Benchmarking (JAXLondon 2015)Benchmarking (JAXLondon 2015)
Benchmarking (JAXLondon 2015)
 
Loom & Functional Graphs in Clojure @ LambdaConf 2015
Loom & Functional Graphs in Clojure @ LambdaConf 2015Loom & Functional Graphs in Clojure @ LambdaConf 2015
Loom & Functional Graphs in Clojure @ LambdaConf 2015
 
Benchmarking (DevNexus 2015)
Benchmarking (DevNexus 2015)Benchmarking (DevNexus 2015)
Benchmarking (DevNexus 2015)
 

Recently uploaded

IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...shyamraj55
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Alan Dix
 
Snow Chain-Integrated Tire for a Safe Drive on Winter Roads
Snow Chain-Integrated Tire for a Safe Drive on Winter RoadsSnow Chain-Integrated Tire for a Safe Drive on Winter Roads
Snow Chain-Integrated Tire for a Safe Drive on Winter RoadsHyundai Motor Group
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
Azure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAzure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAndikSusilo4
 
Next-generation AAM aircraft unveiled by Supernal, S-A2
Next-generation AAM aircraft unveiled by Supernal, S-A2Next-generation AAM aircraft unveiled by Supernal, S-A2
Next-generation AAM aircraft unveiled by Supernal, S-A2Hyundai Motor Group
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024Scott Keck-Warren
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptxLBM Solutions
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 

Recently uploaded (20)

IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Vulnerability_Management_GRC_by Sohang Sengupta.pptx
Vulnerability_Management_GRC_by Sohang Sengupta.pptxVulnerability_Management_GRC_by Sohang Sengupta.pptx
Vulnerability_Management_GRC_by Sohang Sengupta.pptx
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
 
Snow Chain-Integrated Tire for a Safe Drive on Winter Roads
Snow Chain-Integrated Tire for a Safe Drive on Winter RoadsSnow Chain-Integrated Tire for a Safe Drive on Winter Roads
Snow Chain-Integrated Tire for a Safe Drive on Winter Roads
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
Azure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAzure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & Application
 
Next-generation AAM aircraft unveiled by Supernal, S-A2
Next-generation AAM aircraft unveiled by Supernal, S-A2Next-generation AAM aircraft unveiled by Supernal, S-A2
Next-generation AAM aircraft unveiled by Supernal, S-A2
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptx
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 

Clojure class

  • 1. Better Living Through Clojure MIT IAP January 14-15, 2014
  • 2. We are …. Bhaskar (Buro) Mookerji (‘09 VIII , ‘11 VI/MEng) Aysylu Greenberg (‘12 VI-2) David Greenberg (‘11 XVIII-C)
  • 3. Today’s agenda includes... ● ● ● ● ● ● Clojure Overview Syntax: Everything is Data Functions Flow Control Collections Sequences
  • 4. ... and tomorrow: ● ● ● ● ● ● ● ● Testing Concurrency Polymorphism JVM Interop Performance Tooling Interesting Problems Solved by Clojure Our Projects
  • 6. Rationale and Philosophy ● First released by Rich Hickey in 2007 ○ Expressive functional programming with Lisp ○ Designed for concurrency use by default ○ Embedded in an existing platform ● Robust, practical, high-performance ● Simple abstractions backed by powerful ideas
  • 7. The familiar solutions are complex ● Complacency breeds incidental complexity ○ Large programs are difficult to understand ○ Scope of effects are difficult to reason about ○ Concurrency: holy crap. ● “Object-oriented programming is overrated”
  • 8. Clojure is a Lisp About the use of language: it is impossible to sharpen a pencil with a blunt axe. It is equally vain to try to do it with ten blunt axes instead. - Edsger Dijkstra How do we tell truths that might hurt?, EWD498 (Actually John McCarthy.)
  • 9. Clojure is a Lisp ● LISP: code=data, few primitives, abstraction ○ Local maximum in the hierarchy of expression ● Dynamically typed and compiled, interpreted ● Syntactic abstraction through macros ● Clojure: ○ Extends code-as-data to new data structures ○ Modernizes LISP with new ideas from existing functional languages
  • 10. Clojure is Functional and Dynamic ● Functions are first-class ● All data structures are immutable, persistent, recursive, and support heterogeneous types ● Well-defined concurrent behavior ● Strict typing (i.e., Haskell, OCaml) is not everyone nor needed for every application
  • 11. Clojure Runs on the JVM (and Javascript!) ● OS independent ● JVM: Well-supported, existing platform, lots of libraries/platforms ● Static types and safety ● Garbage collection and a great compiler ● Clojurescript: ○ Javascript as the platform: runs everywhere
  • 13. Atomic Literals 22 ;; Long “derp” ;; String 12345678901 ;; BigInt d e r p ;; Character 1.34 ;; Double #”[0-9]+” ;; Regex 1.34M ;; BigDecimal :derp, ::derp ;; Keyword 22/3 ;; Ratio nil ;; null true ;; boolean
  • 14. Atomic Literals 22 ;; Long “derp” ;; String 12345678901 ;; BigInt d e r p ;; Character 1.34 ;; Double #”[0-9]+” ;; Regex 1.34M ;; BigDecimal :derp, ::derp ;; Keyword 22/2 ;; Ratio nil ;; null true ;; boolean Evaluating literals in the REPL: user=> 22 22 user=> ;; ;; ;; ;; Read Eval Print Loop
  • 15. Atomic Literals 22 ;; Long “derp” ;; String 12345678901 ;; BigInt d e r p ;; Character 1.34 ;; Double #”[0-9]+” ;; Regex 1.34M ;; BigDecimal :derp, ::derp ;; Keyword 22/2 ;; Ratio nil ;; null true ;; boolean Evaluating expressions: user=> (+ 2 2) 4 user=> ;; ;; ;; ;; Read Eval Print Loop
  • 16. Atomic Literals 22 ;; Long “derp” ;; String 12345678901 ;; BigInt d e r p ;; Character 1.34 ;; Double #”[0-9]+” ;; Regex 1.34M ;; BigDecimal :derp, ::derp ;; Keyword 22/2 ;; Ratio nil ;; null true ;; boolean Evaluating expressions: user=> ::derp :user/derp user=> ;; ;; ;; ;; Read Eval Print Loop
  • 17. Atomic Literals 22 ;; Long “derp” ;; String 12345678901 ;; BigInt d e r p ;; Character 1.34 ;; Double #”[0-9]+” ;; Regex 1.34M ;; BigDecimal :derp, ::derp ;; Keyword 22/2 ;; Ratio nil ;; null true ;; boolean Evaluating expressions: user=> (class ::derp) clojure.lang.Keyword user=>
  • 18. def binds names user=> pi ;; NOOOOO!! ⇒ Undefined. CompilerException java.lang.RuntimeException: ... user=> (def pi 3.1415926) #'user/pi user=> pi 3.1415926 user=> (println pi) 3.1415926 nil
  • 19. Data Structures ● Lists - singly-linked, front-append ○ (1 2 3 4) ● Vectors - indexed, back-append ○ [:a 2 3 “4”] ● Maps - key/value store ○ {:a 2 :b 4} ● Sets ○ #{:a :b :c :d}
  • 20. Expressions are Data From: http://alandipert.github.io/oscon2012-clojure/
  • 21. Expressions are Data vs… From: http://alandipert.github.io/oscon2012-clojure/
  • 22. Expressions are Data (op ...) ● op can be a …. ○ ○ ○ ○ ○ Function: +, mod, println Macro: when, cond, and Special Operator: do, if, ref Higher-order function … anything callable (clojure.lang.IFn)
  • 23. Function calls use parens... user=> (defn hello [] "Hi!!!") ;; define hello function user=> hello ;; return it #<user$hello user$hello@be1a6e> user=> (hello) ;; invoke it "Hi!!!" … but values never do user=> (def my-name "Kelly Q. Programmer") #'user/my-name user=> my-name "Kelly Q. Programmer" user=>(my-name) ClassCastException java.lang.String cannot be cast to clojure. lang.IFn
  • 24. Quote makes “variables” symbolic user=> (def x 3) #'user/x user=> (+ x 2) 5 user=> '(+ x 2) (+ x 2) ;; quoted list ;; returns list, unevaluated user=> (quote (+ x 2)) (+ x 2) ;; same as above
  • 25. Introspect your Environments user=> (use 'clojure.repl) ;; Quoted symbol user=> (doc if) ;; Print docstring ------------------------if (if test then else?) Special Form Evaluates test. If not the singular values nil or false, evaluates and yields then, otherwise, evaluates and yields else. If else is not supplied it defaults to nil. Please see http://clojure.org/special_forms#if nil
  • 26. Introspect your Environments user=> (source when) (defmacro when "Evaluates test. If logical true, evaluates body in an implicit do." {:added "1.0"} [test & body] (list 'if test (cons 'do body))) nil For More: ● find-doc - Print docstring for var whose doc or name matches a pattern ● apropos - returns a seq of definitions matching a regex ● pst - print stack trace for a given exception or *e by default ● See: http://clojure.org/cheatsheet
  • 27. Namespaces are all around you ● Namespaces disambiguate names ○ vars -> symbols, functions, macros, Java class etc. are all defined in namespaces ● Namespace management is a big part of Clojure development (ns com.your.great.app (:require clojure.string [clojure.set :as set] [clojure.java.io :refer (file reader)]))
  • 29. Functional Abstractions are Useful ● Clojure is functional ● Functions and higher-order functions are generic in a obviously fundamental ways ● clojure.core (mostly) free of side-effects ● TBDL: Immutability and persistence guarantee behavior and performance
  • 30. defn binds functions (defn messenger ;; ([] ;; (messenger "Hi!")) ;; ([msg] ;; (println msg)) ;; ([msg & args] ;; (println msg args))) ;; user=> (messenger) Hi! user=> (messenger "Hi class!") Hi class! user=> (messenger "Hi class!" "Who?" Hello class! (Who? What?) multi-arity definition no args call self with default one arg print it variadic definition apply print to all args "What?")
  • 31. fn creates anonymous functions ● fn creates lambdas (fn ( (fn Hi! nil [message] (println message) ) [message] (println message) ) “Hi!”)
  • 32. apply applies functions ● Invokes argument on arguments (last is a sequence). ;; & puts rest of args into sequence ;; apply pulls args out of sequence (defn messenger [greeting & who] (apply println greeting who)) user=> (messenger "Hi, everyone!" "Who?" "What?") Hi, everyone! Who? What?
  • 33. let binds symbols to values ● Values are either literal or expressions ● Bound symbols have “lexical scope” (defn messenger [msg] (let [a “Who?” b “What?” c (capitalize msg)] (println a b c))) user=> (messenger “Why?”) Who? What? Why?
  • 34. Closures ● Allows bindings to persist beyond the lexical scope (defn messenger-builder [greeting] (fn [who] (println greeting who))) ;; defines closure ;; greeting provided here, then goes out of scope (def hello-er (messenger-builder "Hello")) ;; greeting still available because hello-er is closure user=> (hello-er "world!") Hello world!
  • 36. Expressions in Clojure ● Java, etc. : Expressions return values, but statements do not. ● Clojure: Everything is an expression (-> value or nil) String s; (if (= s “foo”) “bar”) if (s == “foo”) { s = “bar”; } return s; (do (stuff) ;; Do stuff. (= s “foo”) ;; => true
  • 37. Flow Control Operators ● if, when, if-not, when-not, do, cond, case, etc. are all flow control operators. ● composable and general
  • 38. “Truthiness” (if (if (if (if true :truthy :falsey) (Object.) :truthy :falsey) [] :truthy :falsey) 0 :truthy :falsey) ;;=> :truthy, and so are: ;; objects ;; empty collections ;; zero (if false :truthy :falsey) (if nil :truthy :falsey) (if (seq []) :truthy :falsey) ;;=> :falsey ;; nil ;; seq on empty collection (and true 0 22) ;; returns last expression (or true false 22)
  • 39. if, do, and when user => (if (even? 5) ;; if is multibranch (do (println "Even!") ;; do evaluates block and true) ;; returns last value (do (println "Odd!") false)) odd ;; printed false ;; return value user => (when (even? 5) (println "Even!") true) ;; when is single-branch ;; sugar for (if <>(do..))
  • 40. cond and case (let [x 22] ;; Compares predicates (cond (<= x 22) "Dismissed as coincidence." (> x 222) "x is greater than 222." :else "No conditions met")) (defn bazbar [x] (case x 22 "x is 22" 222 "x is 222" "x is neither 22 or 222")) ;; Matches arguments ;; in O(1) time ;; Must be literals
  • 41. Iterations (and side effects) (dotimes [i 5] (println i)) ;; Evals and returns nil. (doseq [letter [:a :b :c] ;; Imperative cartesian product. number (range 5)] (println [letter number])) (for [letter [:a :b :c] number (range 5)] [letter number]) ;; Sequence cartesian product. ;; ([:a 0] [:a 1] [:a 2] [:b 0] ;; [:b 1] [:b 2] …)
  • 42. Threading Macros Remove Nesting ;; Deeply-nested parens ... (first (.split (.replace (.toUpperCase "a b c d") "A" "X") " ")) ;; ... are unwinded with thread-first macro (-> "a b c d" .toUpperCase (.replace "A" "X") (.split " ") first) ;; Also ->>, as->, cond->, cond->>, etc.
  • 43. Recursion (with loop/recur) ● loop binds, recur re-loops ● Strong prefer iteration and higher-order functions over recursion (loop [i 0] (if (< i 22) (recur (inc i)) i)) 22
  • 44. Today …. ● ● ● ● ● ● Intro to Clojure Clojure Overview & REPL Functions Flow Control Collections Sequences
  • 45. Collections ● Extensive facilities for representing and manipulating data ● Small number of data structures ● Seq abstraction common across data structures ● Large library of functions across all of them
  • 46. Collections: Immutability ● Simple (numbers, strings) and compound values are immutable ● Key to Clojure's concurrency model ● Cannot change immutable values ○ Generate new ones instead ○ Persistent data structures for efficiency
  • 47. Collections: Persistent Data Structures ● New values = old values + modifications ● New values are not full copies ● New value and old value are both available after 'changes' ● Performance guarantees for most operations ● All Clojure data structures are persistent
  • 50. Collections: Data Structures ● Sequential: list ○ ○ ○ ○ Singly-linked lists Prepend: O(1) Lookup: O(1) at head, O(n) anywhere else Grow at the head (front)
  • 51. Collections: Data Structures ● Sequential: list () ;=> the empty list (:a :b :c) ; error because :a not function '(:a :b :c) ;=> (:a :b :c) (list :a :b :c) ;=> (:a :b :c) (conj '(:b :c) :a) ;=> (:a :b :c)
  • 52. Collections: Data Structures ● Sequential: list, vector
  • 53. Collections: Data Structures ● Sequential: list, vector ○ ○ ○ ○ Indexed, random-access, array-like Append: O(1) * Lookup: O(1) * Grow at the tail (end) O(1) * = O(log 32 n), really close to O(1), is O(1) for n < 1 billion
  • 54. Collections: Data Structures ● Sequential: list, vector [] ;=> the empty vector [:a :b :c] ;=> [:a :b :c] (vector :a :b :c) ;=> [:a :b :c] (vec '(:a :b :c)) ;=> [:a :b :c] (nth [:a :b :c] 0) ;=> :a (conj [:a :b] :c) ;=> [:a :b :c]
  • 55. Collections: Data Structures ● Sequential: list, vector ● Associative: map
  • 56. Collections: Data Structures ● Sequential: list, vector ● Associative: map ○ Key → value, hash table, dictionary ○ Insert and lookup: O(1) * ○ Unordered
  • 57. Collections: Data Structures ● Sequential: list, vector ● Associative: map {} {:a "a" :b "b"} (get {:a "a"} :a) (get {:a "a"} :z) (get {:a "a"} :z 22) ;;=> the empty map ;;=> {:a "a" :b "b"} ;;=> "a" ;;=> nil ; not found ;;=> 22 ; default (assoc {:a "a"} :b "b") ;;=> {:a "a" :b "b"} (dissoc {:a "a"} :a) ;;=> {} (conj {} [:a "a"]) ;;=> {:a "a"}
  • 58. Collections: Data Structures ● Sequential: list, vector ● Associative: map ○ Nested access: get-in, assoc-in, update-in (def our-class {:class "Better Living Through Clojure" :location {:room "4-231"})
  • 59. Collections: Data Structures ● Sequential: list, vector ● Associative: map ○ Nested access: get-in, assoc-in, update-in (def our-class {:class "Better Living Through Clojure" :location {:room "4-231"}) (get (get our-class :location) :room) ;;=> "4-231"
  • 60. Collections: Data Structures ● Sequential: list, vector ● Associative: map ○ Nested access: get-in, assoc-in, update-in (def our-class {:class "Better Living Through Clojure" :location {:room "4-231"}) (get (get our-class :location) :room) ;;=> "4-231" (-> our-class (get :location) (get :room)) ;;=> "4-231"
  • 61. Collections: Data Structures ● Sequential: list, vector ● Associative: map ○ Nested access: get-in, assoc-in, update-in (def our-class {:class "Better Living Through Clojure" :location {:room "4-231"}) (get (get our-class :location) :room) ;;=> "4-231" (-> our-class (get :location) (get :room)) ;;=> "4-231" (get-in our-class [:location :room]) ;;=> "4-231"
  • 62. Collections: Data Structures ● Sequential: list, vector ● Associative: map, set
  • 63. Collections: Data Structures ● Sequential: list, vector ● Associative: map, set ○ ○ ○ ○ Set of distinct values Insert: O(1) * Member?: O(1) * Unordered
  • 64. Collections: Data Structures ● Sequential: list, vector ● Associative: map, set #{} #{"a" "b"} ;;=> the empty set ;;=> #{"a" "b"} (set ["a" "b"]) ;;=> #{"a" "b"} (conj #{} "a") ;;=> #{"a"} (contains? #{"a"} "a") ;;=> true
  • 65. Collections: Data Structures are Functions ● Maps are functions of their keys (def dict {:a "a" :b "b"}) (dict :b) ;;=> "b"
  • 66. Collections: Data Structures are Functions ● Maps are functions of their keys (def dict {:a "a" :b "b"}) (dict :b) ;;=> "b" ● Keywords are functions of maps (:b dict) ;;=> "b"
  • 67. Collections: Data Structures are Functions ● Maps are functions of their keys (def dict {:a "a" :b "b"}) (dict :b) ;;=> "b" ● Keywords are functions of maps (:b dict) ;;=> "b" ● Sets are functions of their elements (def s #{3 7 9}) (s 7) ;;=> 7
  • 68. Collections: Data Structures are Functions ● Maps are functions of their keys (def dict {:a "a" :b "b"}) (dict :b) ;;=> "b" ● Keywords are functions of maps (:b dict) ;;=> "b" ● Sets are functions of their elements (def s #{3 7 9}) (s 7) ;;=> 7 ● Vectors are functions of their indices (def v [:a :b :c]) (v 1) ;;=> :b
  • 69. Collections: Destructuring ● Declarative way to pull apart compound data ○ vs. explicit, verbose access ● Sequential & associative data structures ● Nests for deep, arbitrary access ● Works in fn and defn params, let bindings
  • 70. Collections: Destructuring ;; Without destructuring: (defn next-fib-pair [pair] [(second pair) (+ (first pair) (second pair))])
  • 71. Collections: Destructuring ;; Without destructuring: (defn next-fib-pair [pair] [(second pair) (+ (first pair) (second pair))]) ;; With destructuring: (defn next-fib-pair [[x y]] [y (+ x y)])
  • 72. Today …. ● ● ● ● ● ● ● Intro to Clojure Clojure Overview & REPL Functions Flow Control Names & Namespaces Collections Sequences
  • 73. Sequences ● Abstraction for representing iteration ● Backed by a data structure or a function ○ Can be lazy and/or "infinite" ● Foundation for large library of functions
  • 74. Sequences: API ● (seq coll) ○ If collection is not empty, return seq object on it ○ If collection is empty, return nil
  • 75. Sequences: API ● (seq coll) ○ If collection is not empty, return seq object on it ○ If collection is empty, return nil ● (first coll) returns the first element
  • 76. Sequences: API ● (seq coll) ○ If collection is not empty, return seq object on it ○ If collection is empty, return nil ● (first coll) returns the first element ● (rest coll) returns a sequence of the rest of the elements
  • 77. Sequences: API ● (seq coll) ○ If collection is not empty, return seq object on it ○ If collection is empty, return nil ● (first coll) returns the first element ● (rest coll) returns a sequence of the rest of the elements ● (cons x coll) returns a new sequence: first is x, rest is coll
  • 78. Sequences: Example (seq [1 2 3]) ;=> (1 2 3) ; not a list (seq "Clojure") ;=> (C l o j u r e) (seq {:a 1 :b 2}) ;=> ([:a 1] [:b 2]) ; seq of map entries (seq a-java-array) ;=> (...) (seq []) (seq "") (seq {}) ;=> nil ;=> nil ;=> nil
  • 79. Sequences: Over Structures ● We can treat any data structure as a seq (def s '(1 2 3)) ; s is a list s 1 2 3
  • 80. Sequences: Over Structures ● We can treat any data structure as a seq (def s '(1 2 3)) (def a (first s)) ; s is a list ; a is 1 s a 1 2 3
  • 81. Sequences: Over Structures ● We can treat any data structure as a seq (def s '(1 2 3)) ; s is a list (def r (rest s)) ; r is a seq s r 1 2 3
  • 82. Sequences: Over Structures ● We can treat any data structure as a seq (def s '(1 2 3)) ; s is a list (def b (first (rest s)) ; b is 2 (def b (second s)) ; same thing s 1 b 2 3
  • 83. Sequences: Over Structures ● We can treat any data structure as a seq ○ Lists are seqs ○ Others are wrapped ○ Associative structures become sequence of pairs
  • 84. Sequences: Over Functions ● Can map a generator function to a seq ● Seq is lazy, can be infinite ● Can process more than fits in memory (def (def (def (def (def (def (def r (range 1 100)) ; r is a lazy seq a (first r)) ; a is 1 s (rest r)) ; s is a lazy seq b (first (rest r)) ; b is 2 b (second r)) ; same thing c (first (rest (rest r)))) ; c is 3 c (nth r 2)) ; same thing
  • 85. Sequences: Generation (range) ;=> (0 1 2 ... infinite (range 5) ;=> (0 1 2 3 4) (repeat :b) ;=> (:b :b :b ... infinite (repeatedly #(rand-int 100)) ;=> (89 58 73 ... infinite
  • 86. Sequences: Into Collections (into #{} "hello") ;=> #{e h l o} (into {} [[:x 1] [:y 2]]) ;=> {:x 1, :y 2} (into () [:a :b :c]) ;=> (:c :b :a)
  • 87. Sequences: Shorten (take 3 (range)) ;=> (0 1 2) (drop 3 (range)) ;=> (3 4 5 ... infinite (filter even? (range)) ;=> (0 2 4 6 ... infinite (remove even? (range)) ;=> (1 3 5 7 ... infinite
  • 88. Sequences: Lengthen (concat [:a :b] (range 2 5)) (cycle [:a :b :c]) (interpose , (range 3)) ;=> (:a :b 2 3 4) ;=> (:a :b :c :a :b ... infinite ;=> (0 , 1 , 2)
  • 89. Sequences: map (map even? (range 1 5)) ;=> (false true false true) (map + [1 2 3] [4 5 6]) ;=> (5 7 9) (map * [1 2 3] (range 1000)) ;=> (0 2 6)
  • 90. Sequences: reduce (reduce function init seq) ● ● ● ● function takes 2 arguments: accumulator and the current argument reduce calls (function init (first seq)) Return value becomes init for next step Repeat until the end of the seq, returns the last init (reduce (fn [total item] (+ total (* 10 item))) 0 ; init [1 2 3 4]) ;=> 100
  • 91. Sequences: some (some even? [1 2 3 4]) ;=> true (some #{:foo} [:baz :bar :foo]) ;=> :foo
  • 92. Combine sequence functions: Power ;; Sum of the first 50 odd integers (reduce + (take 50 (filter odd? (range)))) ;=> 2500 ;; Top 5 most frequently used words in the docstrings of the current namespace (->> (ns-publics *ns*) (map (comp :doc meta val)) (remove nil?) (mapcat (fn [s] (re-seq #"w+" s))) (frequencies) (sort-by val) (reverse) (take 5) (map first))
  • 93. In this Class ● ● ● ● ● ● ● ● Testing Concurrency Polymorphism JVM Interop Performance Tooling Interesting Problems Solved by Clojure Our Projects
  • 94. clojure.test (deftest math-basics (is (= 3 (+ 1 2))) (is (= 10 (* 2 5))) (is (thrown? java.lang.ArithmeticException (/ 1 0))))
  • 95. midje (fact (+ 1 2) => 3 (* 2 5) => 10 (/ 1 0) => (throws java.lang.ArithmeticException))
  • 96. expectations (expect 3 (+ 1 2)) (expect 10 (* 2 5)) (expect java.lang.ArithmeticException (/ 1 0))
  • 97. In this Class ● ● ● ● ● ● ● ● Testing Concurrency Polymorphism JVM Interop Performance Tooling Interesting Problems Solved by Clojure Our Projects
  • 98. Benefits of Immutability ● What is a race condition? ● How does immutability help?
  • 99. Atoms ;; Create atom with initial value (def a (atom 0)) ;; Atomically transition from old to new value (swap! a (fn [old-value] (+ 3 old-value))) ;; Set to a new value, regardless of old value (reset! a 22)
  • 100. Refs and Agents ● Refs allow you do many “swap!”s transactionally ○ aka Software Transactional Memory ● Agents allow you do do “swap!”s asynchronously on a thread pool ○ a dual of actors: send functions to the value, rather than values (messages) to the function (actor)
  • 101. core.async ● Go-style communicating sequential processes ● “select” operator ● Scalable user-space scheduling ● Works in ClojureScript ● See the talk from Clojure Conj here
  • 102. In this Class ● ● ● ● ● ● ● ● Testing Concurrency Polymorphism JVM Interop Performance Tooling Interesting Problems Solved by Clojure Our Projects
  • 103. Two kinds of polymorphism Protocols Multimethods Dispatch The first argument’s type Arbitrary function of all arguments Performance Fast; uses native virtual dispatch Slow; requires a hash table lookup Popularity Extremely popular, good reputation Used only when arbitrary dispatch is necessary
  • 104. Protocols ● Solves the expression problem ○ “How can we extend existing functions to new datatypes and new functions to existing datatypes without recompiling all code?” ● Uses perfect hashing and Java interfaces for dispatching
  • 105. Protocols - Example (defprotocol ITaskRunner (run [this task] "run the task, which is a fn")) (defrecord ThreadRunner [name] ITaskRunner (run [this task] (future (task))) (defrecord ImmediateRunner [nickname] ITaskRunner (run [this task] (task))) (run (->ThreadRunner "Bob") (fn [] (println "hello world from thread"))) (run (->ImmediateRunner "Lily") (fn [] (println "hello world from stack")))
  • 106. Protocols - Example (defprotocol INamed (named [this] "Return the name of this")) (extend-protocol INamed TaskRunner (named [this] (:name this)) ImmediateRunner (named [this] (:nickname this))) (named (->ThreadRunner "Bob")) ;;=> "Bob" (named (->ImmediateRunner "Lily")) ;;=> "Lily"
  • 107. Multimethods - Example ;; We define a multimethod with its dispatch function (defmulti battle "Engage 2 spacecraft in epic battle" (fn [x y] [(:type x) (:type y)])) ;; We can even create hierarchies of keywords. ;; Java types are permissible as leaves (derive :x-wing :ship)
  • 108. Multimethods - Example ;; We can define arbitrary numbers of implementations (defmethod battle [:death-star :planet] [death-star planet] (str planet " has been obliterated by " death-star)) (defmethod battle [:ship :star-destroyer] [ship destroyer] (str ship " has been eliminated by " destroyer "defenses")) (defmethod battle [:x-wing :death-star] [x-wing death-star] (str x-wing " perfectly shot its proton torpedoes into " death-star))
  • 109. In this Class ● ● ● ● ● ● ● ● Testing Concurrency Polymorphism JVM Interop Performance Tooling Interesting Problems Solved by Clojure Our Projects
  • 111. Making your own Exceptions (try (throw (ex-info "A data-carrying exception" {:x 22 :y 42})) (catch clojure.lang.ExceptionInfo e (println ":x is" (:x (ex-data e)))))
  • 112. Java Interop Task Java Clojure Instantiation new MyClass(“foo”) (MyClass. “foo”) Instance method dog.bark() (.bark dog) Instance field object.field (.-field object) Static method Math.sin(22) (Math/sin 22) Static field Math.PI Math/PI
  • 113. Java Methods vs. Clojure Functions ;; Works (map str (range 10)) ;; Doesn’t work (map .toString (range 10)) ;;Works (map (fn [x] (.toString x)) (range 10))
  • 114. Clojure Types are Java Types Clojure Type Java Type Long java.lang.Long Double java.lang.Double Boolean java.lang.Boolean String java.lang.String Regex java.util.regex.Pattern BigDecimal java.lang.BigDecimal BigInt clojure.lang.BigInt (wraps java.lang.BigInteger or long)
  • 115. Clojure Types are Java Types Clojure Type Java Type Function java.lang.Runnable, java.util.concurrent.Callable List java.util.List * Vector java.util.List * Map java.util.Map * Set java.util.Set * * Does not include mutation operators, like add() or put()
  • 116. In this Class ● ● ● ● ● ● ● ● Testing Concurrency Polymorphism JVM Interop Performance Tooling Interesting Problems Solved by Clojure Our Projects
  • 117. How long did it take? ;;Built-in (simple) (time (dotimes [i 1000] (+ 1 1))) ;;Criterium (statistically robust) (criterium.core/bench (+ 1 1))
  • 118. Clojurians care about Speed ● ● ● ● ● Transient collections Protocols Unboxed numeric support in the compiler no.dissassemble (inspect bytecode of fn) Performance-oriented libraries ○ core.async - user space threading ○ core.matrix - matrix math ○ narrator - time series analysis
  • 119. What’s in your toolkit? Complex Simple State, Objects, Methods Values, Functions/Namespaces Variables Managed references and concurrency Inheritance, switch, matching Polymorphism Syntax Data Imperative loops, folds Sequence Functions Conditionals Rules Inconsistency Consistency and Design “Paradigms” Syntactic Abstraction
  • 120. In this Class ● ● ● ● ● ● ● ● Testing Concurrency Polymorphism JVM Interop Performance Tooling Interesting Problems Solved by Clojure Our Projects
  • 121. Leiningen ● “for automating Clojure projects without setting your hair on fire” ● Functional project management ● Fetches dependencies and constructs classpath ● Packages and deploys project ● Easily extensible with plugins
  • 122. Leingen - usage lein lein lein lein new my-cool-project repl uberjar deploy clojars (defproject my-cool-project "0.1.0-SNAPSHOT" ... :dependencies [[org.clojure/clojure "1.4.0"] [ring "1.2.1"]])
  • 123. Vim ● fireplace ○ ○ ○ ○ Simple evaluation Prefix intellisense Documentation lookup Go to source ● redl ○ Advanced REPL with simple debugger ○ Fuzzy intellisense
  • 124. Emacs ● cider ○ ○ ○ ○ Advanced REPL Documentation lookup Symbol completion Source lookup ● ritz ○ Stepping debugger via JVM’s debugging API ○ All features of cider
  • 125. Light Table ● ● ● ● Easiest to get started REPL Inline documentation Written in Clojure(Script)!
  • 126. Paredit + Rainbow Parens ● It’s really hard to keep parens, braces, and brackets matching ● It’s really hard to see which ones are pairs ● Let your editor handle it!
  • 127. In this Class ● ● ● ● ● ● ● ● Testing Concurrency Polymorphism JVM Interop Performance Tooling Interesting Problems Solved by Clojure Our Projects
  • 128. Clojure Toolbox ● clojure-toolbox.com ● Great starting point for projects! ● Database clients, web frameworks, data structures, parsers, etc.
  • 129. ● Purely functional database ● Horizontal read scalability
  • 130. Storm ● Hadoop for realtime data ● Used by Twitter to process all tweets in real-time (and by many others!)
  • 131. Riemann ● Event processor and monitoring tool for distributed systems ● Makes it easy to monitor clusters, calculate statistics, and send alerts
  • 132. Instaparse What if context-free grammars were as easy to use as regular expressions? (insta/parser "S = AB* AB = A B A = 'a'+ B = 'b'+")
  • 133. In this Class ● ● ● ● ● ● ● ● Testing Concurrency Polymorphism JVM Interop Performance Tooling Interesting Problems Solved by Clojure Our Projects
  • 134. Sources ● http://clojure.org ● Talks by Rich Hickey: Clojure, Are We There Yet, and Simple Made Easy ● Beating the Averages, Paul Graham