the curious clojurist - neal ford (thoughtworks)
DESCRIPTION
Presented at JAX London 2013 Clojure is the most interesting new language on the horizon, but many developers suffer from the Blub Paradox when they see the Lisp syntax. This talk introduces Clojure to developers who haven’t been exposed to it yet, focusing on the things that truly set it apart from other languages.TRANSCRIPT
![Page 1: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/1.jpg)
The Curious Clojure-ist
1
![Page 2: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/2.jpg)
Agenda Data
Data as Code
Destructuring
Macros
Protocols
The Expression Problem
Concurrency
2
![Page 3: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/3.jpg)
Data
3
![Page 4: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/4.jpg)
datahttps://github.com/edn-format/edn
Extensible Data Notationednedn
4
![Page 5: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/5.jpg)
edn Person5
![Page 6: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/6.jpg)
edn ⊇ Clojure syntax
used by Datomic and others as data transfer format
language/implementation neutral
edn is a system for the conveyance of values.
characteristicsedn
edn is a system for the conveyance of values.
6
![Page 7: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/7.jpg)
a type system
schema based
a system for representing objects
edn is a system for the conveyance of values.
NOT:
7
![Page 8: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/8.jpg)
Scalars
nil nil, null, or nothing
booleans true or false
stringsenclosed in “double quotes”
may span multiple lines\t \r \n supported
characters\c
\newline, \return, \space and \tab
8
![Page 9: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/9.jpg)
Scalars
integers0-9
negative
floating point 64-bit (double) precision is expected.
9
![Page 10: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/10.jpg)
Names
symbols
used to represent identifiersshould map to something other than strings
may include namespace prefixs:my-namespace/foo
keywords
identifiers that designate themselvessemantically akin to enumeration values
symbols that must start with ::fred or :my/fred
10
![Page 11: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/11.jpg)
Collections
listsa sequence of values
zero or more elements within ()(a b 42)
vectors
a sequence of values……that supports random access
zero or more elements within [][a b 42]
11
![Page 12: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/12.jpg)
Collections
maps
collection of key/value associationsevery key should appear only once
unorderedzero or more elements within {}
{:a 1, "foo" :bar, [1 2 3] four}
sets
collection of unique valuesunordered
heterogeneouszero or more elements within #{}
#{a b [1 2 3]}
12
![Page 13: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/13.jpg)
Data as Code
13
![Page 14: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/14.jpg)
Clojure Syntax
edn + …
14
![Page 15: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/15.jpg)
Functions
fn callarg
semantics:
structure:stringsymbol
list
15
![Page 16: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/16.jpg)
Operators (No Different than Functions)
fn call args
list
16
![Page 17: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/17.jpg)
Defining Functions17
![Page 18: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/18.jpg)
defn Semanticsdefine a
fn fn namedocstring
arguments
fn body
18
![Page 19: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/19.jpg)
defn Structure
symbol symbolstring
vector
list
19
![Page 20: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/20.jpg)
Multi-arity
functionmeta-data
20
![Page 21: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/21.jpg)
Control Flow
21
![Page 22: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/22.jpg)
Decisions
true branch
false branch
22
![Page 23: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/23.jpg)
Decisions
23
![Page 24: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/24.jpg)
Refactor
More Arities
24
![Page 25: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/25.jpg)
Don’t Forget…
25
![Page 26: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/26.jpg)
(source …)
26
![Page 27: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/27.jpg)
Namespaces
27
![Page 28: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/28.jpg)
Namespace Declaration
(ns com.example.foo)
names correspond to Java packages,imply same directory structure
28
![Page 29: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/29.jpg)
Namespace Declaration
(ns com.example.foo (:require clojure.data.generators clojure.test.generative))
load some libs
29
![Page 30: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/30.jpg)
Namespace Declaration
(ns com.example.foo (:require [clojure.data.generators :as gen] [clojure.test.generative :as test]))
provide short aliasesfor other libs
30
![Page 31: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/31.jpg)
Namespace Declaration
(ns ^{:author "Stuart Halloway" :doc "Data generators for Clojure."} clojure.data.generators (:refer-clojure :exclude [byte char long ...]) (:require [clojure.core :as core]))
namespace metadata
31
![Page 32: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/32.jpg)
Don’t Do This
(ns com.example.foo (:use clojure.test.generative))
“:use” makes all names unqualified
32
![Page 33: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/33.jpg)
Seqs
33
![Page 34: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/34.jpg)
Sequences Abstraction of traditional Lisp lists
(seq coll)
if collection is non-empty, return seq object on it, else nil
(first seq)
returns the first element
(rest seq)
returns a sequence of the rest of the elements
34
![Page 35: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/35.jpg)
Laziness Most of the core library functions that produce
sequences do so lazily
e.g. map, filter etc
And thus if they consume sequences, do so lazily as well
Avoids creating full intermediate results
Create only as much as you consume
Work with infinite sequences, datasets larger than memory
35
![Page 36: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/36.jpg)
Sequences(drop 2 [1 2 3 4 5]) -> (3 4 5)
(take 9 (cycle [1 2 3 4]))-> (1 2 3 4 1 2 3 4 1)
(interleave [:a :b :c :d :e] [1 2 3 4 5])-> (:a 1 :b 2 :c 3 :d 4 :e 5)
(partition 3 [1 2 3 4 5 6 7 8 9])-> ((1 2 3) (4 5 6) (7 8 9))
(map vector [:a :b :c :d :e] [1 2 3 4 5])-> ([:a 1] [:b 2] [:c 3] [:d 4] [:e 5])
(apply str (interpose \, "asdf"))-> "a,s,d,f"
(reduce + (range 100)) -> 495036
![Page 37: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/37.jpg)
Seq Cheat Sheet
clojure.org/cheatsheet
37
![Page 38: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/38.jpg)
Vectors
38
![Page 39: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/39.jpg)
(def v [42 :rabbit [1 2 3]])
(v 1) -> :rabbit
(peek v) -> [1 2 3]
(pop v) -> [42 :rabbit]
(subvec v 1) -> [:rabbit [1 2 3]]
(contains? v 0) -> true ; subtle
(contains? v 42) -> false ; subtle
Vectors
39
![Page 40: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/40.jpg)
Maps
40
![Page 41: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/41.jpg)
(def m {:a 1 :b 2 :c 3})
(m :b) -> 2 ;also (:b m)
(keys m) -> (:a :b :c)
(assoc m :d 4 :c 42) -> {:d 4, :a 1, :b 2, :c 42}
(dissoc m :d) -> {:a 1, :b 2, :c 3}
(merge-with + m {:a 2 :b 3}) -> {:a 3, :b 5, :c 3}
Maps
41
![Page 42: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/42.jpg)
Nested Structures(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}}
42
![Page 43: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/43.jpg)
Sets(use clojure.set)(def colors #{"red" "green" "blue"})(def moods #{"happy" "blue"})
(disj colors "red")-> #{"green" "blue"}
(difference colors moods)-> #{"green" "red"}
(intersection colors moods)-> #{"blue"}
(union colors moods)-> #{"happy" "green" "red" "blue"}
bonus: all relational algebra primitives
supported forsets-of-maps
43
![Page 44: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/44.jpg)
Destructuring
44
![Page 45: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/45.jpg)
Pervasive Destructuring
DSL for binding names
Works with abstract structure
Available wherever names are made*
Vector binding forms destructure sequential things
Map binding forms destructure associative things
45
![Page 46: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/46.jpg)
Why Destructure?
(defn next-fib-pair [pair] [(second pair) (+ (first pair) (second pair))])
(iterate next-fib-pair [0 1])-> ([0 1] [1 1] [1 2] [2 3] [3 5] [5 8] [8 13]...)
without destructuring, next-fib-pair is dominated by code to “pick apart” pair
destructure it yourself…
46
![Page 47: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/47.jpg)
Sequential Destructure
(defn next-fib-pair [[a b]] [b (+ a b)])
(iterate next-fib-pair [0 1])-> ([0 1] [1 1] [1 2] [2 3] [3 5] [5 8] [8 13] ...)
…or you can do the samething with a simple []
47
![Page 48: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/48.jpg)
Simple Things Inline
(defn fibs [] (map first (iterate (fn [[a b]] [b (+ a b)]) [0 1])))
which makes next-fib-pairso simple that you willprobably inline it away!
48
![Page 49: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/49.jpg)
Associative Data
(defn format-name [person] (str/join " " [(:salutation person) (:first-name person) (:last-name person)]))
(format-name {:salutation "Mr." :first-name "John" :last-name "Doe"})-> "Mr. John Doe"
same problem as before:code dominated bypicking apart person
49
![Page 50: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/50.jpg)
Associative Destructure
(defn format-name [name] (let [{salutation :salutation first-name :first-name last-name :last-name} name] (str/join " " [salutation first-name last-name]))
(format-name {:salutation "Mr." :first-name "John" :last-name "Doe"})-> "Mr. John Doe"
pick apart name
50
![Page 51: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/51.jpg)
The :keys Option
(defn format-name [{:keys [salutation first-name last-name]}] (str/join " " [salutation first-name last-name]))
(format-name {:salutation "Mr." :first-name "John" :last-name "Doe"})-> "Mr. John Doe"
a common scenario:parameter names and key names are the same, so say
them only once
51
![Page 52: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/52.jpg)
Optional Keyword Args
(defn game [planet & {:keys [human-players computer-players]}] (println "Total players: " (+ human-players computer-players))) (game "Mars” :human-players 1 :computer-players 2)Total players: 3
not a language feature, simply a consequence of variable arity fns
plus map destructuring
52
![Page 53: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/53.jpg)
Platform Interop
53
![Page 54: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/54.jpg)
Java new
java new Widget("foo")
clojure sugar (Widget. "red")
54
![Page 55: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/55.jpg)
Access Static Members
java Math.PI
clojure sugar Math/PI
55
![Page 56: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/56.jpg)
Access Instance Members
java rnd.nextInt()
clojure sugar (.nextInt rnd)
56
![Page 57: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/57.jpg)
Chaining Access
java person.getAddress().getZipCode()
clojure sugar (.. person getAddress getZipCode)
57
![Page 58: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/58.jpg)
Parenthesis Count
java ()()()()
clojure ()()()
58
![Page 59: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/59.jpg)
all forms are created equal !
interpretation is everything
59
![Page 60: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/60.jpg)
form syntax example
function list (println "hello")operator list (+ 1 2)
method call list (.trim " hello ")import list (require 'mylib)
metadata list (with-meta obj m)control flow list (when valid? (proceed))
scope list (dosync (alter ...))
all forms are created equal !
60
![Page 61: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/61.jpg)
Special Forms
61
![Page 62: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/62.jpg)
Special Forms (def symbol init?)
(if test then else?)
(do exprs*)
(quote form)
(fn name? [params*] exprs*)
(fn name? ([params*] exprs*)+)
(let [bindings*] exprs*)
(loop [bindings*] exprs*)
(recur exprs*)
(throw expr)
(try expr* catch-clause* finally-clause?)
62
![Page 63: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/63.jpg)
Macros
63
![Page 64: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/64.jpg)
Programs writing Programs
Reader
evaluator/compiler
Effect
data structures
Code
Text
bytecode
You
JVM
characters
characters
Program
data structures
Reader
evaluator/compiler
Effect
data structures
Code
Text
bytecode
You
JVM
characters
characters
Program
data structures
Program(macro)
data structures
64
![Page 65: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/65.jpg)
Inside Out?
{:name "Jonathan"}
(assoc {:name "Jonathan"} :nickname "Jon")
(dissoc (assoc {:name "Jonathan" :password "secret"} :nickname "Jon") :password)
65
![Page 66: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/66.jpg)
Thread First ->
(-> {:name "Jonathan" :password "secret"} (assoc :nickname "Jon") (dissoc :password))
(dissoc (assoc {:name "Jonathan" :password "secret"} :nickname "Jon") :password)
66
![Page 67: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/67.jpg)
Syntactic Abstraction
Reader
evaluator/compiler
Effect
data structures
Code
Text
bytecode
You
JVM
characters
characters
Program
data structures
Program(macro)
data structures
67
![Page 68: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/68.jpg)
Seq Ops Inside Out
(range 10)
(map inc (range 10))
(filter odd? (map inc (range 10)))
(reduce + (filter odd? (map inc (range 10))))
68
![Page 69: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/69.jpg)
Thread Last ->>
(->> (range 10) (map inc) (filter odd?) (reduce +))
(reduce + (filter odd? (map inc (range 10))))
69
![Page 70: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/70.jpg)
defrecord
70
![Page 71: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/71.jpg)
AFn
IFn
ifn?
AFunction
APersistentVector
APersistentMap
APersistentSet
Keyword
MultiFn
Ref
RestFn
Symbol
Var Callability
Fn
fn?
71
![Page 72: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/72.jpg)
From Maps...(def stu {:fname "Stu" :lname "Halloway" :address {:street "200 N Mangum" :city "Durham" :state "NC" :zip 27701}})
(:lname stu)=> "Halloway"
keyword access
(-> stu :address :city)=> "Durham"
nested access
(assoc stu :fname "Stuart")=> {:fname "Stuart", :lname "Halloway", :address ...}
update
(update-in stu [:address :zip] inc)=> {:address {:street "200 N Mangum", :zip 27702 ...} ...}
nestedupdate
data oriented
72
![Page 73: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/73.jpg)
...to Records!(defrecord Person [fname lname address])(defrecord Address [street city state zip])(def stu (Person. "Stu" "Halloway" (Address. "200 N Mangum" "Durham" "NC" 27701)))
(:lname stu)=> "Halloway"
(-> stu :address :city)=> "Durham"
(assoc stu :fname "Stuart")=> :user.Person{:fname "Stuart", :lname"Halloway", :address ...}
(update-in stu [:address :zip] inc)=> :user.Person{:address {:street "200 N Mangum", :zip 27702 ...} ...}
still data-oriented:everything works
as beforetype is therewhen you
care
object oriented
73
![Page 74: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/74.jpg)
defrecord(defrecord Foo [a b c])-> user.Foo
named typewith slots
(def f (Foo. 1 2 3))-> #'user/f positional
constructor(:b f)-> 2 keyword
access(class f)-> user.Foo plain ol'
class(supers (class f))-> #{clojure.lang.IObj clojure.lang.IKeywordLookup java.util.Map clojure.lang.IPersistentMap clojure.lang.IMeta java.lang.Object java.lang.Iterable clojure.lang.ILookup clojure.lang.Seqable clojure.lang.Counted clojure.lang.IPersistentCollection clojure.lang.Associative}
casydht*
*Clojure abstracts so you don't have to
74
![Page 75: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/75.jpg)
Protocols
75
![Page 76: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/76.jpg)
(defprotocol AProtocol "A doc string for AProtocol abstraction" (bar [a b] "bar docs") (baz [a] "baz docs"))
Named set of generic functions
Polymorphic on type of first argument
No implementation
Define fns in the same namespaces as protocols
Protocols
76
![Page 77: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/77.jpg)
Extending Protocols
77
![Page 78: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/78.jpg)
Extend Protocols Inline
(defrecord Bar [a b c] AProtocol (bar [this b] "Bar bar") (baz [this] (str "Bar baz " c)))
(def b (Bar. 5 6 7))
(baz b)
=> "Bar baz 7"
78
![Page 79: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/79.jpg)
Extend Protocols Inlinefrom ClojureScript
browser.clj
79
![Page 80: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/80.jpg)
Extending to a Type(baz "a")
java.lang.IllegalArgumentException: No implementation of method: :baz of protocol: #'user/AProtocol found for class: java.lang.String
(extend-type String AProtocol (bar [s s2] (str s s2)) (baz [s] (str "baz " s)))
(baz "a")
=> "baz a"
80
![Page 81: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/81.jpg)
Extending to Many Types
from Clojurereducers.clj
note extendto nil
81
![Page 82: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/82.jpg)
Extending to Many Protocols
from ClojureScriptcore.cljs
82
![Page 83: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/83.jpg)
Composition with Extend
from Clojure java/io.clj
the “DSL” for advanced reuse is maps and assoc
83
![Page 84: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/84.jpg)
Reify
(let [x 42 r (reify AProtocol (bar [this b] "reify bar") (baz [this ] (str "reify baz " x)))] (baz r))
=> "reify baz 42"
instantiate an unnamed type implement 0
or more protocols
or interfaces
closes overenvironment
like fn
84
![Page 85: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/85.jpg)
Code Structurepackage com.acme.employees;
Employee
raise()
roles()
updatePersonalInfo()
Manager
roles()
approvalProfile()
interface Employee {}
(namespace com.acme.employees)
(raise )
(updatePersonalInfo )
(roles )
(approvalProfile )
(defprotocol Employee )
85
![Page 86: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/86.jpg)
The Expression Problem
86
![Page 87: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/87.jpg)
The Expression Problem
abstraction
concretion
A B
A should be able to work with B's abstractions, and vice versa,
without modification of the original code
87
![Page 88: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/88.jpg)
Is This Really a Problem?
abstraction
concretion
just use interfaces for abstraction (??)
BA
88
![Page 89: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/89.jpg)
Example: ArrayList vs.the Abstractions
java.util.List
ArrayList
clojure.lang.Counted
clojure.lang.Seqable
?89
![Page 90: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/90.jpg)
Example: String vs.the Abstractions
java.util.List
String clojure.lang.Counted
clojure.lang.Seqable
?
90
![Page 91: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/91.jpg)
A Can't Inherit from B
B is newer than A
A is hard to change
We don’t control A
happens even within a single library!
91
![Page 92: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/92.jpg)
Some Approachesto the Expression
Problem
92
![Page 93: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/93.jpg)
1. Roll-your-own
if/then instanceof? logic
closed
93
![Page 94: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/94.jpg)
A Closed World
94
![Page 95: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/95.jpg)
so make a NiftyString
that is
2. Wrappers
NiftyString
java.util.List
String
java.util.Collectionstrings are
not collections
95
![Page 96: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/96.jpg)
Wrappers = Complexity
Ruin identity
Ruin Equality
Cause nonlocal defects
Don’t compose: AB + AC ≠ ABC
Have bad names
96
![Page 97: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/97.jpg)
3. Monkey Patching
common in e.g. rubynot possible in java
String
java.util.List
java.util.Collectionsneak in
and change them!
strings are not
collections
97
![Page 98: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/98.jpg)
Monkey Patching = Complexity
Preserves identity (mostly)
Ruins namespacing
Causes nonlocal defects
Forbidden in some languages
98
![Page 99: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/99.jpg)
4. Generic Functions (CLOS)
don't touch existing implementation,
just use it
String
map
reduce
count
polymorphism lives in the
fns
99
![Page 100: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/100.jpg)
Generic Functions
Decouple polymorphism & types
Polymorphism in the fns, not the types
no “isa” requirement
no type intrusion necessary
100
![Page 101: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/101.jpg)
protocols = generic functions - arbitrary dispatch + speed + grouping
(and still powerful enough tosolve the expression problem!)
101
![Page 102: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/102.jpg)
Concurrency
102
![Page 103: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/103.jpg)
concurrency, coincidence of events or space
parallelism, the execution of operations concurrently by separate parts of a computer
103
![Page 104: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/104.jpg)
Our Tools
threads
104
![Page 105: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/105.jpg)
Our Tools
42
places
105
![Page 106: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/106.jpg)
critical sections
Our Tools
42
42 42
106
![Page 107: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/107.jpg)
memory, the capacity ... for returning to a previous state when the cause of the transition from that state is removed
record, the fact or condition of having been written down as evidence...... an authentic or official report
107
![Page 108: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/108.jpg)
Memory, Records = Places?
Memory is small and expensive
Storage is small and expensive
Machines are precious, dedicated resources
Applications are control centers
108
![Page 109: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/109.jpg)
A Different Approach
New memories use new places
New records use new places
New moments use new places
“In-place” changes encapsulated by constructors
109
![Page 110: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/110.jpg)
Values
110
![Page 111: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/111.jpg)
Values
Immutable
Maybe lazy
Cacheable (forever!)
Can be arbitrarily large
Share structure
111
![Page 112: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/112.jpg)
What Can Be a Value?
42
112
![Page 113: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/113.jpg)
What Can Be a Value?
{:first-name "Stu", :last-name "Halloway"}
42
113
![Page 114: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/114.jpg)
What Can Be a Value?
42{:first-name "Stu", :last-name "Halloway"}
114
![Page 115: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/115.jpg)
What Can Be a Value?
42{:first-name "Stu", :last-name "Halloway"}
115
![Page 116: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/116.jpg)
What Can Be a Value?
42{:first-name "Stu", :last-name "Halloway"}
Anything?
116
![Page 117: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/117.jpg)
References
Refer to values (or other references)
Permit atomic, functional succession
Model time and identity
Compatible with a wide variety of update semantics
117
![Page 118: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/118.jpg)
Epochal Time Model
v1 v2 v3
values
118
![Page 119: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/119.jpg)
Epochal Time Model
v1 v2 v3
f1 f2
functions
119
![Page 120: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/120.jpg)
Epochal Time Model
v1 v2 v3
f1 f2
atomic succession
120
![Page 121: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/121.jpg)
Epochal Time Model
v1 v2 v3
f1 f2
reference
121
![Page 122: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/122.jpg)
Epochal Time Model
v1 v2 v3
f1 f2
observers perceive identity, can remember and record
122
![Page 123: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/123.jpg)
Epochal Time Model
v1 v2 v3
f1 f2
observers do notcoordinate
123
![Page 124: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/124.jpg)
Epochal Time Model
v1 v2 v3
f1 f2
124
![Page 125: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/125.jpg)
Atoms
125
![Page 126: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/126.jpg)
Atoms
(def a (atom 0))
(swap! a inc)=> 1
(compare-and-set! a 0 42)=> false
(compare-and-set! a 1 7)=> true
126
![Page 127: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/127.jpg)
Atoms
(def a (atom 0))
(swap! a inc)=> 1
(compare-and-set! a 0 42)=> false
(compare-and-set! a 1 7)=> true
functional succession
127
![Page 128: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/128.jpg)
Atoms
(def a (atom 0))
(swap! a inc)=> 1
(compare-and-set! a 0 42)=> false
(compare-and-set! a 1 7)=> true
optimistic concurrency
128
![Page 129: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/129.jpg)
Software Transactional Memory
129
![Page 130: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/130.jpg)
Software Transactional Memory
Refs can change only within a transaction
Provides the ACI in ACID
Transactions are speculative, will be retried
130
![Page 131: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/131.jpg)
F
v1 v2 v3 v4
v1 v2 v3 v4
v1 v2 v3 v4
v1 v2 v3 v4
F
F
F
F
F
F
F F F
F
F
Transactions131
![Page 132: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/132.jpg)
Transactions
(defn transfer [from to amount] (dosync (alter from - amount) (alter to + amount)))
(alter from - 1)=> IllegalStateException No transaction running
132
![Page 133: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/133.jpg)
(defn transfer [from to amount] (dosync (alter from - amount) (alter to + amount)))
(alter from - 1)=> IllegalStateException No transaction running
Transactions
scope transaction
133
![Page 134: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/134.jpg)
(defn transfer [from to amount] (dosync (alter from - amount) (alter to + amount)))
(alter from - 1)=> IllegalStateException No transaction running
Transactions
functional succession
134
![Page 135: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/135.jpg)
Transactions
(defn transfer [from to amount] (dosync (alter from - amount) (alter to + amount)))
(alter from - 1)=> IllegalStateException No transaction running
coordination guaranteed!
135
![Page 136: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/136.jpg)
STM Details
Uses locks, latches internally to avoid churn
Deadlock detection and barging
No read tracking
Readers never impede writers
Nobody impedes readers
136
![Page 137: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/137.jpg)
Summary
137
![Page 138: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/138.jpg)
Summary
Serious Lisp on the JVM
Built as a destination
Advanced language features
Advanced implementation
Secret weapon?
138
![Page 139: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/139.jpg)
Clojure in the wild?“We re-coded our flagship application XXXXXX from Java to Clojure about a year ago. NEVER looked back. Why?
Reduced our lines of code down by at least half.
Support and bugs have likewise been cut by about 65-70%.
We have large enterprise clients. How did we get Clojure into these very old guard environments????
139
![Page 140: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/140.jpg)
Between you and me....
We don't talk about Clojure. We talk about "Java Extensions" or "the Clojure Java Extension". No one is the wiser.Clients LOVE us for our blistering fast turn around. We present ourselves as a larger company with fake Linkedin employees. We actually only have 4 real employees. But with Clojure we do the same work as if we had 20.”
we lie.
140
![Page 141: The Curious Clojurist - Neal Ford (Thoughtworks)](https://reader033.vdocuments.site/reader033/viewer/2022050906/554a07c5b4c905557a8b56ec/html5/thumbnails/141.jpg)
?’sThe preceding work is licensed under the Creative Commons Attribution-Share Alike 3.0 License.
http://creativecommons.org/licenses/by-sa/3.0/us/
Presentation PatternsNeal Ford, Matthew McCullough, Nathaniel Schuttahttp://presentationpatterns.com
Functional Thinking bit.ly/nf_ftvideo
Clojure (inside out)Neal Ford, Stuart Hallowaybit.ly/clojureinsideout
141