for rubyists http://github.com/stuarthalloway/clojure-presentations
TRANSCRIPT
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 1/123
Copyright 2007-2009 Relevance, Inc. This presentation is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License. See http://creativecommons.org/licenses/by-nc-sa/3.0/us/
stuart halloway
1
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 2/123
assumptions
2
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 3/123
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 4/123
syntax
4
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 5/123
data literals
type properties example
listsingly-linked,
insert at front
(1 2 3)
vectorindexed,
insert at rear[1 2 3]
map key/value {:a 100:b 90}
set key #{:a :b}
5
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 6/123
homiconicity:code is data
6
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 7/123
(concat [1 2] [3 4])-> (1 2 3 4)
function call
7
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 8/123
(+ 1 2)
-> 3
(+ 1 2 3)
-> 6
“operators”
8
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 9/123
(defn
hello
"Returns greeting that includes name" [name]
(str "Hello, " name))
-> #'user/hello
function definitions
9
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 10/123
(if hell-freezes-over(skate!)
(roast!))
control flow
10
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 11/123
(.. "stupid"
(substring 0 3)(toUpperCase))
-> "STU"
java interop
11
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 12/123
(try
(/ 1 0)(catch ArithmeticException e
"should have expected that"))
error handling
12
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 13/123
(ns demo
(:use clojure.contrib.pprint
compojure)(:import java.io.File)
(:require
[clojure.http.resourcefully
:as r]))
namespaces and imports
13
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 14/123
atomic data types
type example java equivalentstring "foo" String
character \f Character
regex #"fo*" Pattern
a. p. integer 42 Integer/Long/BigInteger
double 3.14159 Double
a.p. double 3.14159M BigDecimal
boolean TRUE Boolean
nil nil null
symbol foo, + N/A
keyword :foo, ::foo N/A14
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 15/123
homiconic benefits
easy to parse
regularity simplifies metaprogramming
data library = metaprogramming library
"language" features are library code
15
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 16/123
example:
higher-order
functions
16
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 17/123
lunch-companions
-> ({:fname "Neal", :lname "Ford"} {:fname "Stu", :lname "Halloway"}
{:fname "Dan", :lname "North"})
some data
17
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 18/123
(defn last-name [x](get x :last-name)
“getter” function
fn name arg list (vector)
body
18
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 19/123
(sort-byfirst-name
lunch-companions)
-> ({:fname "Dan", :lname "North"}
{:fname "Neal", :lname "Ford"}
{:fname "Stu", :lname "Halloway"})
pass fn to fn
call fnfn arg
data arg
19
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 20/123
(sort-by(fn [n]
(get n :fname))
lunch-companions)
anonymous fn
anonymous fn
fn arg
body
20
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 21/123
(sort-by#(get % :fname)
lunch-companions)
anonymous #()
anonymous fn
fn arg
21
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 22/123
(sort-by#(% :fname)
lunch-companions)
maps are functions
map is fn!
22
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 23/123
(sort-by#(:fname %)
lunch-companions)
keywords are functions
keywordis fn!
23
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 24/123
(sort-by :fname lunch-companions)
beautiful
24
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 25/123
good implementations
have a 1-1 ratio of pseudocode/code
25
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 26/123
1. sequencelibrary
26
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 27/123
(first [1 2 3])
-> 1
(rest [1 2 3])-> (2 3)
(cons "hello" [1 2 3])
-> ("hello" 1 2 3)
first / rest / cons
27
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 28/123
(take 2 [1 2 3 4 5])
-> (1 2)
(drop 2 [1 2 3 4 5])
-> (3 4 5)
take / drop
28
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 29/123
(range 10)
-> (0 1 2 3 4 5 6 7 8 9)
(filter odd? (range 10))-> (1 3 5 7 9)
( map odd? (range 10))
-> (false true false true false true
false true false true)
(reduce + (range 10))
-> 45
map / filter / reduce
29
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 30/123
(sort [ 1 56 2 23 45 34 6 43])
-> (1 2 6 23 34 43 45 56)
(sort > [ 1 56 2 23 45 34 6 43])
-> (56 45 43 34 23 6 2 1)
(sort-by #(.length %)["the" "quick" "brown" "fox"])
-> ("the" "fox" "quick" "brown")
sort
30
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 31/123
(conj '(1 2 3) :a)
-> (:a 1 2 3)
(into '(1 2 3) '(:a :b :c))-> (:c :b :a 1 2 3)
(conj [1 2 3] :a)
-> [1 2 3 :a]
(into [1 2 3] [:a :b :c])
-> [1 2 3 :a :b :c]
conj / into
31
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 32/123
(set! *print-length* 5)
-> 5
(iterate inc 0)-> (0 1 2 3 4 ...)
(cycle [1 2])
-> (1 2 1 2 1 ...)
(repeat :d)
-> (:d :d :d :d :d ...)
lazy, infinite sequences
32
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 33/123
(interpose \, ["list" "of" "words"])
-> ("list" \, "of" \, "words")
(apply str
(interpose \, ["list" "of" "words"]))
-> "list,of,words"
(use 'clojure.contrib.str-utils)
(str-join \, ["list" "of" "words"]))
-> "list,of,words"
interpose
33
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 34/123
(every? odd? [1 3 5])
-> true
(not-every? even? [2 3 4])-> true
(not-any? zero? [1 2 3])
-> true
(some nil? [1 nil 2])
-> true
predicates
34
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 35/123
(def jdoe {:name "John Doe",
:address {:zip 27705, ...}})
(get-in jdoe [:address :zip])-> 27705
(assoc-in jdoe [:address :zip] 27514)
-> {:name "John Doe", :address {:zip 27514}}
(update-in jdoe [:address :zip] inc)
-> {:name "John Doe", :address {:zip 27706}}
nested ops
35
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 36/123
Ash zna durbatulûk,ash zna gimbatul,
ash zna thrakatulûk agh burzum-ishi
krimpatul.
36
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 37/123
2. persistent datastructures
37
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 38/123
persistent data structures
immutable
“change” by function application
maintain performance guarantees
full-fidelity old versions
38
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 39/123
persistent example:
linked list
tigerrabbitternnewt
“my” list“your”
list
39
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 40/123
bit-partitioned tries
“your”trie
“my”trie
40
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 41/123
log2 n:too slow!
41
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 42/123
32-way tries
... ... ... ... ... ...
... ...
... ......
... ......
42
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 43/123
clojure: ‘cause
log32 n is
fast enough!
43
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 44/123
3. values, identity,and state
44
bl i
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 45/123
mutable oo is
incoherentidentity
???
identity
???
?
45
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 46/123
mutable objects don't compose
mutation crosscuts contracts
duck typing doesn't help
"deadlocks like a duck" ?
"corrupts like a duck" ?
coordination required even for reads
no general way to be lazy/cachedcode reading is recursive speculation
46
d ff
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 47/123
cause and effect
if reuse will
take the form of
objects composewell
objects
objects composepoorly
domain-limited frameworksand plugins withconstrained non-language
semantics for state
47
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 48/123
clojure
identity value
identity value
value
explicit semantic
state
48
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 49/123
terms
1. value: immutable data in a persistent datastructure
2. identity: series of causally related values
over time3. state: identity at a point in time
49
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 50/123
identity types (references)
shared isolated
synchronous/coordinated
refs/stm -
synchronous/autonomous
atoms vars
asynchronous/autonomous
agents -
50
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 51/123
4. unifiedupdate model
51
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 52/123
refs and stm
52
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 53/123
(def messages (ref ()))
ref example: chat
identity
initial value
53
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 54/123
(deref messages)
-> ()
@messages
-> ()
reading value
54
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 55/123
Code
alter
r
oldval
newval
(alter r update-fn & args)
55
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 56/123
Code
alter
r
oldval
newval
(alter r update-fn & args)
(apply update-fn
oldval
args)
55
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 57/123
fi d d d l
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 58/123
unified update model
update by function application
readers require no coordination
readers never block anybody
writers never block readers
additional semantics per ref type
automatic retry
sync/async
shared/isolated
57
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 59/123
a sane approach
to local statepermits coordination,
but does not require it
58
fi d d d l
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 60/123
unified update model
ref atom agent var
create ref atom agent def
deref deref/@ deref/@ deref/@ deref/@
update alter swap! send
alter-
var-
root
59
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 61/123
atoms
60
http://blog.bestinclass.dk/index.php/2009/10/brians-functional-brain/
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 62/123
p g p p
61
b d i j l
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 63/123
(defn new-board
"Create a new board with about half the cells set
to :on."
([] (apply new-board dim-board))
([dim-x dim-y]
(for [x (range dim-x)]
(for [y (range dim-y)]
(if (< 50 (rand-int 100)) :on :off))))))
board is just a value
distinct bodies by arity
62
d i j f i
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 64/123
(defn step
"Advance the automation by one step, updating all
cells."
[board]
(doall
( map (fn [ window ]
(apply #(doall (apply map rules %&))
(doall ( map torus-window window))))
(torus-window board))))
update is just a function
rules
cursor over previous, me, next
63
i i i l
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 65/123
(let [stage (atom (new-board))]
...)
(defn update-stage
"Update the automaton."
[stage]
(swap! stage step))
state is trivial
identity initial value
apply a fn update fn
64
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 66/123
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 67/123
agents
66
d
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 68/123
send
caller fixed threadpool
(send a fn & args)
(apply fn oldval args)
agent
67
l d f d l i
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 69/123
(def *logging-agent* (agent nil))
(if log-immediately?(impl-write! log-impl level msg err)
(send-off *logging-agent*
agent-write! log level msg err))
example: deferred logging
identity initial value
apply a fn “update” fn
68
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 70/123
vars
69
d f f t
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 71/123
(def greeting "hello")
(defn make-greeting [n]
(str "hello, " n)
def forms create vars
70
b b d
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 72/123
vars can be rebound
api scope
alter-var-root root binding
set! thread-local, permanent
binding thread-local, dynamic
71
t tti
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 73/123
(set! *print-length* 20)
=> 20
primes
=> (2 3 5 7 11 13 17 19 23 29 31 37 4143 47 53 59 61 67 71 ...)
(set! *print-length* 5)
=> 5
primes
=>(2 3 5 7 11 ...)
system settings
72
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 74/123
var usage
*in*, *out*, *err* standard streams
*print-length*,
*print-depth*structure printing
*warn-on-reflection* performance tuning
*ns* current namespace
*file* file being evaluated
*command-line-args* guess
73
ith h l
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 75/123
(def bar 10)
-> #'user/bar
( with-ns 'foo (def bar 20))
-> #'foo/bar
user/bar
-> 10
foo/bar
-> 20
with-... helper macros
bind a varfor a dynamic
scope
74
h d f f
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 76/123
form usage
defonce set root binding once
defvar var plus docstring
defunbound no initial binding
defstruct map with slots
defalias same metadata as original
defhinted infer type from initial binding
defmemo defn + memoize
other def forms
many of these are in clojure.contrib.def...
75
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 77/123
5. multimethods
76
l hi
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 78/123
square.draw(canvas)
circle.draw(canvas)
p
f1(square, canvas)
f2(circle, canvas)
polymorphism
77
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 79/123
this isn’t special
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 80/123
square.draw(canvas)
circle.draw(canvas)
p(this, that){return this.class;}
f1(square, canvas)
f2(circle, canvas)
this isn t special
79
check all args
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 81/123
(fn [this, that]
[(class this)
(class that)])
(fn [square, canvas])
check all args
(fn [circle, canvas])
(fn [square, surface])
(fn [circle, surface])
80
check arg twice
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 82/123
(fn [this, that]
[(class this)
(opaque? this)
(class that)])
check arg twice
fn1
fn2
fn3fn4
fn5
fn6
fn7
fn8
81
example: coerce
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 83/123
(defmulti coerce
(fn [dest-class src-inst]
[dest-class (class src-inst)]))
example: coerce
define amultimethod
based ondest (a class)
and src(an inst)
82
method impls
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 84/123
(defmethod coerce
[java.io.File String]
[ _ str]
(java.io.File. str))
(defmethod coerce
[Boolean/TYPE String] [ _ str]
(contains? #{"on" "yes" "true"}
(.toLowerCase str)))
method impls
dispatch valueto match
argsbody
83
defaults
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 85/123
(defmethod coerce
:default [dest-cls obj]
(cast dest-cls obj))
defaults
84
dispatch comparison
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 86/123
dispatch comparison
language java ruby clojure
basic polymorphism? ✔ ✔ ✔
change “methods” at
runtime?
✔ ✔
change “types” at runtime? ✔ ✔
dispatch based onall ar uments?
* ✔
arbitrary fn dispatch? * ✔
pattern matching * *
85
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 87/123
dispatch workarounds
are the middlemanagers of the design
patterns movement
86
class inheritance
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 88/123
(defmulti whatami? class)
(defmethod whatami? java.util.Collection
[ _ ] "a collection")
(whatami? (java.util.LinkedList.))
-> "a collection"
(defmethod whatami? java.util.List
[ _ ] "a list")
(whatami? (java.util.LinkedList.))
-> "a list"
class inheritance
most derived
type wins
add methods
anytime
87
name inheritance
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 89/123
(defmulti interest-rate :type)
(defmethod interest-rate ::account
[ _ ] 0M)
(defmethod interest-rate ::savings
[ _ ] 0.02)
name inheritance
double colon (::) is shorthand for resolvingkeyword into the current namespace, e.g.
::savings == :my.current.ns/savings
88
deriving names
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 90/123
(derive ::checking ::account)(derive ::savings ::acount)
(interest-rate {:type ::checking})
-> 0M
deriving names
base namederived name
there is no ::checking method, so selectmethod for base name ::account
89
multimethods lfu
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 91/123
multimethods lfufunction notes
prefer-method resolve conflicts
methods reflect on {dispatch, meth} pairs
get-method reflect by dispatch
remove-method remove by dispatch
prefers reflect over preferences
90
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 92/123
6. macros
91
the if special form
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 93/123
(if test
thenelse?)
the if special form
evaluate only
if test islogical true
evaluate onlyif test islogical false
92
if-like things
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 94/123
if -like things
cannot be functions!function calls
evaluate their argspass args to implementation
if
evaluates an arg
decides which other args to evaluate, and when
93
lisp macros
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 95/123
lisp macros
get access to source formsafter they are read
before compile/interpret
macroexpand forms into other forms
choose when/how to evaluate each argument
94
example: when
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 96/123
example: when
(defmacro when
[test & body]
(list
'if test
(cons 'do body)))
( when x
(println "x is true")))
(if x
(do (println "x is true")))
macroexpansion
95
quoting and list-building
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 97/123
(defmacro when
[test & body]
(list'if test
(cons 'do body)))
quoting and list-building
quotinglist-building
96
syntax-quoting
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 98/123
(defmacro when
[test & body]
(list'if test
(cons 'do body)))
syntax-quoting
syntax-quote
(defmacro when
[test & body]
`(if ~test(do ~@body)))
unquote-splicing
unquote
=
97
test your macros!
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 99/123
( macroexpand-1
'( when x
(println "x is true")))
-> (if x
(do (println "x is true")))
test your macros!
98
a bench macro
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 100/123
not done yet...
(defmacro bench [expr]`(let [start (System/nanoTime) result ~expr]
{:result result
:elapsed (- (System/nanoTime)start)}))
a bench macro
99
capture?
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 101/123
not done yet...
(defmacro bench [expr]`(let [start (System/nanoTime) result ~expr]
{:result result
:elapsed (- (System/nanoTime)start)}))
capture?
could thesecollide withnames in scope
of expr?
100
avoiding accidental capture
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 102/123
not done yet...
(defmacro bench [expr]`(let [start (System/nanoTime) result ~expr]
{:result result
:elapsed (- (System/nanoTime)start)}))
avoiding accidental capture
(bench (x))
-> java.lang.Exception:Can't let qualified name: user/start
101
use auto-gensyms
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 103/123
(defmacro bench [expr]`(let [start# (System/nanoTime) result# ~expr]
{:result result#
:elapsed (- (System/nanoTime)start#)}))
use auto gensyms
# suffix generates uniquesymbol within a quoted form
102
generated symbols
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 104/123
( macroexpand-1 '(bench (x)))
-> (clojure.core/let
[start __37__auto__ (java.lang.System/nanoTime)
result __38__auto__ (x)] {:result result __38__auto__,
:elapsed (clojure.core/-
(java.lang.System/nanoTime)
start __37__auto__ )})
generated symbols
103
common macro types
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 105/123
type examples
control flow when when-not and or
vars defn defmacro defmulti
java interop .. doto deftype proxy
rearranging -> ->> -?>
scopes dosync time with-open
“special form” fn lazy-seq let
104
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 106/123
7. metadata
105
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 107/123
metadata:data that is
orthogonal to the
value of an object
106
metadata uses
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 108/123
metadata uses
documentation
serialization
protection
optimization
relationships (e.g. test -> testee)
grouping/typing (?)
107
add & retrieve metadata
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 109/123
(def x ( with-meta
{:password "swordfish"}
{:secret true}))
-> #'user/x
x
-> {:password "swordfish"}
( meta x)
-> {:secret true}
add & retrieve metadata
data
metadata
retreivemetadata
add
metadata
108
sugar: #^, ^
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 110/123
(def y #^{:secret true}
{:password "swordfish"}))
-> #'user/y
^y
-> {:secret true}
sugar: # , add
metadata metadatafirst!
retrievemetadata
109
subtleties
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 111/123
metadata can be on data, or on a var
to place metadata on a var:
put it on the symbol when defing the var
compiler will copy it to the var
metadata cannot be added to a function
110
var: add metadata
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 112/123
(def #^{:secret true} z
{:password "swordfish"})
-> #'user/z
^z
-> nil
var: add metadataadd
metadata to symbol
z’s data has no metadata
111
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 113/123
type metadata example
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 114/123
(defn capitalize
"Upcase the first character of a string,
lowercase the rest."
[s]
(if (.isEmpty s)s
(let [up (.. s
(substring 0 1)
(toUpperCase))
down (.. s(substring 1)
(toLowerCase))]
(.concat up down))))
yp p
113
*warn-on-reflection*
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 115/123
(set! *warn-on-reflection* true)-> true
(require :reload 'demo.capitalize)
Reflection warning, demo/capitalize.clj:6 -
reference to field isEmpty can't be resolved.
Reflection warning, demo/capitalize.clj:8 -call to substring can't be resolved.
Reflection warning, demo/capitalize.clj:8 -
call to toUpperCase can't be resolved.
Reflection warning, demo/capitalize.clj:11 -
call to substring can't be resolved.
Reflection warning, demo/capitalize.clj:11 -call to toLowerCase can't be resolved.
Reflection warning, demo/capitalize.clj:14 -
call to concat can't be resolved.
-> nil
114
add type metadata
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 116/123
(defn capitalize "Upcase the first character of a string,
lowercase the rest."
[#^String s]
(if (.isEmpty s)
s(let [up (.. s
(substring 0 1)
(toUpperCase))
down (.. s
(substring 1)(toLowerCase))]
(.concat up down))))
yp
s is known to be a String
115
no more warnings
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 117/123
(set! *warn-on-reflection* true)
-> true
(require :reload 'demo.capitalize)
-> nil
g
116
more idiomatic
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 118/123
(defn capitalize
"Upcase the first character of a string,
lowercase the rest."
[#^String s]
(if (.isEmpty s)s
(.concat
(.toUpperCase (subs s 0 1))
(.toLowerCase (subs s 1)))))
still non-reflective,
if subs is non-reflective
117
var metadata convenience
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 119/123
form usage
defonce set root binding once
defvar var plus docstring
defunbound no initial binding
defstruct map with slots
defalias same metadata as original
defhinted infer type from initial binding
defmemo defn + memoize
many of these are in clojure.contrib.def...
118
seven reasons
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 120/123
lazy sequencespersistent data structures
values, identity, and state
unified update model
multimethods
macrosmetadata
119
love, sex, friendship
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 121/123
ruby clojure
built for love built for love
consenting adults consenting adults
friendship friendship
, , p
120
variety
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 122/123
ruby clojure
mutable objects
ad hoc update model
immutable data
unified update model
open classes
open instances
"copying" is cheap
multimethods ~ "open fns"
many tasteful hooks
flexible punctuation
macros
homoiconicity
y
121
8/14/2019 For Rubyists Http://Github.com/Stuarthalloway/Clojure-presentations
http://slidepdf.com/reader/full/for-rubyists-httpgithubcomstuarthallowayclojure-presentations 123/123
MeEmail: [email protected]
Office: 919-442-3030Twitter: stuarthalloway
Facebook: stuart.halloway
Github: stuarthalloway
TalkingThis talk: github.com/stuarthalloway/
clojure-presentations
Talks: blog.thinkrelevance.com/
talks
WritingBlog: blog.thinkrelevance.com
Book: tinyurl.com/clojure