clojure: the art of abstraction
DESCRIPTION
Clojure is a new language that combines the power of Lisp with an existing hosted VM ecosystem (the Java VM). Clojure is a dynamically typed, functional, compiled language with performance on par with Java.At the heart of all programming lies the need for abstraction, be it abstraction over our data or abstraction over the processes that operate upon it. Clojure provides a core set of powerful abstractions and ways to compose them. These abstractions are based in a heritage of Lisp but also cover many aspects of object-oriented programming as well. This talk will examine these abstractions and introduce you to both Clojure and functional programming. Attendees are not expected to be familiar with either Clojure or FP.TRANSCRIPT
![Page 1: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/1.jpg)
“The Art of Abstraction”
Alex MillerRevelytix
Clojure
![Page 2: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/2.jpg)
Why are We Here?
![Page 3: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/3.jpg)
Why are We Here?
I think abstraction is central to what we do as programmers.
![Page 4: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/4.jpg)
Why are We Here?
I think abstraction is central to what we do as programmers.
I think Clojure is a great language for creating abstractions.
![Page 5: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/5.jpg)
What is abstraction?
"Abstraction is the elimination of the irrelevant and the amplification of the essential."
- Bob Martin
![Page 6: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/6.jpg)
"I've been doing a lot of abstract painting lately... extremely abstract. No brush, no paint, no canvas. I just think about it."
- Steven Wright
![Page 7: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/7.jpg)
Clojure
•A Lisp dialect on the JVM (and CLR)
•Dynamically typed
•Compiled
![Page 8: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/8.jpg)
"When we describe a language, we should pay particular attention to the means that the language provides for combining simple ideas to form more complex ideas. Every powerful language has three mechanisms for accomplishing this:
1. primitive expressions, which represent the simplest entities the language is concerned with
2. means of combination, by which compound elements are built from simpler ones
3. means of abstraction, by which compound elements can be named and manipulated as units "
Structure and Interpretation of Computer Programs - Abelson, Sussman, Sussman
![Page 9: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/9.jpg)
Primitive Expressionsnil
numbers
strings
characters
symbols
keywords
nil
1, 2.3, 22/7
"abc"
\a, \b, \space
math/fib
:bar
![Page 10: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/10.jpg)
Means of combination
2 3
![Page 11: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/11.jpg)
Means of combination
2 3 + 2 3
![Page 12: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/12.jpg)
Means of combination
(+ 2 3) 2 3 + 2 3
![Page 13: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/13.jpg)
Means of combination
(+ 2 3) 2 3 + 2 3Expression
![Page 14: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/14.jpg)
Means of combination
(+ 2 3) 2 3 + 2 3Expression
Evaluate
![Page 15: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/15.jpg)
Means of combination
(+ 2 3) 2 3 + 2 3Expression
Evaluate
![Page 16: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/16.jpg)
Means of combination
(+ 2 3) 2 3 + 2 3Expression
Evaluate
![Page 17: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/17.jpg)
Means of combination
(+ 2 3) 2 3 + 2 3Expression
Invoke
![Page 18: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/18.jpg)
(fn [x] (* x x))
Means of abstraction
![Page 19: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/19.jpg)
(def square (fn [x] (* x x)))
Means of abstraction
![Page 20: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/20.jpg)
(def square (fn [x] (* x x)))
Means of abstraction
(defn square [x] (* x x))
![Page 21: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/21.jpg)
Abstracting with functions
![Page 22: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/22.jpg)
Abstracting with functions
(defn square [x] (* x x))
![Page 23: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/23.jpg)
Abstracting with functions
(defn square [x] (* x x))
(defn cube [x] (* x x x))
![Page 24: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/24.jpg)
Abstracting with functions
(defn square [x] (* x x))
(defn cube [x] (* x x x))
(defn exp [x n] (apply * (repeat n x)))
![Page 25: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/25.jpg)
Abstracting with functions
(defn exp [x n] (case n 0 1 1 x (* x (exp x (dec n)))))
(exp 2 3)(* x (exp 2 2))(* x (* x (exp 2 1)))(* x (* x x))
![Page 26: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/26.jpg)
Abstracting with functions
(defn exp [x n] (loop [total 1 counter n] (if (= counter 0) total (recur (* x total) (dec counter)))))
![Page 27: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/27.jpg)
Abstracting with functions
(defn exp [x n])
![Page 28: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/28.jpg)
"It is better to have 100 functions operate on one data structure than to have 10 functions operate on 10 data structures."
- Alan J. Perlis“Epigrams in Programming” http://www.cs.yale.edu/quotes.html
![Page 29: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/29.jpg)
Collections
List
Vector
Set
Map
(1 2 3)
[1 2 3]
#{1 2 3}
{:a 1 :b 2 :c 3}
![Page 30: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/30.jpg)
All data and collections are IMMUTABLE
![Page 31: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/31.jpg)
All data and collections are IMMUTABLE
![Page 32: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/32.jpg)
Structural sharing(def a '(1 2 3))
![Page 33: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/33.jpg)
(def b (cons 4 a))
Structural sharing(def a '(1 2 3))
![Page 34: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/34.jpg)
(def b (cons 4 a))
(def c (cons 5 (rest a)))
Structural sharing(def a '(1 2 3))
![Page 35: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/35.jpg)
What do all collections share in common?
![Page 36: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/36.jpg)
What do all collections share in common?
sequential traversal over values
![Page 37: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/37.jpg)
What do all collections share in common?
sequential traversal over values
"seq"
![Page 38: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/38.jpg)
Iterator Models
Java IteratorC#
IEnumerator Clojure seq
more? hasNext MoveNext not null
get next Current first
next next MoveNext rest
*table stolen from Rich Hickey’s talk on sequences
![Page 39: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/39.jpg)
seq
1 2 3 4 5
vector seq first rest
nil nil nil ()
nil nil ()
(1 2 3 4 5) 1 (2 3 4 5)
![Page 40: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/40.jpg)
Seq and ye shall find...• String
• Java Collections
• Java Iterators (iterator-seq, enumeration-seq)
• ResultSet (resultset-seq)
• Trees (tree-seq)
• XML (xml-seq)
• Lines of a file (line-seq)
• Files in a directory (file-seq)
![Page 41: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/41.jpg)
Lazy seqs
(take 10 (iterate inc 1))
(1 2 3 4 5 6 7 8 9 10)
![Page 42: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/42.jpg)
Functions on Collections and
Sequences
![Page 43: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/43.jpg)
Collection TraitsList Vector
Set Map
conjfirstcountseq
listlist?
peekpopnth
vectorvec
vector-ofsubvecvector?
getassocdissoc
select-keys
replace
hash-mapsorted-map
zipmapkeysvalsmap?
hash-setsorted-set
disj
contains?
findmerge
merge-with
SequentialCountedSeqable
ReversibleIndexed
AssociativeSequentialCountedSeqable
CountedSeqable
AssociativeCountedSeqable
![Page 44: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/44.jpg)
Lists
(def a '(1 2 3)) #'user/a(def b (cons 0 a)) #'user/b(first b) 0(rest b) (1 2 3)(count b) 4(nth b 1) 1
![Page 45: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/45.jpg)
Vectors
(def v [1 2 3]) #'user/v(def w (conj v 4)) #'user/w(nth w 3) 4(get w 3) 4
Vectors are associative -
indices are keys
![Page 46: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/46.jpg)
Maps
(def m {:a 1 :b 2}) #'user/m(def n (assoc m :c 3)) #'user/n(keys n) (:c :a :b)(vals n) (3 1 2)(get m :a) 1(m :a) 1(:a m) 1
Data as code
![Page 47: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/47.jpg)
Sequence Functions
![Page 48: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/48.jpg)
Sequence Functions
(range 6) (0 1 2 3 4 5)(filter odd? (range 6)) (1 3 5)(reverse (range 4)) (3 2 1 0)(partition 2 (range 4)) ((0 1) (2 3))(map inc (range 5)) (1 2 3 4 5)(reduce + (range 10)) 45
![Page 49: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/49.jpg)
Higher order functions
(defn mult [x] (fn [y] (* x y)))#'user/mult
(def x10 (mult 10))#'user/x10
(map x10 (range 5))(0 10 20 30 40)
![Page 50: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/50.jpg)
Functional Kingdom"In Javaland, by King Java's royal decree, Verbs are owned by Nouns."
"In the Functional Kingdoms, Nouns and Verbs are generally considered equal-caste citizens. However, the Nouns, being, well, nouns, mostly sit around doing nothing at all. They don't see much point in running or executing anything, because the Verbs are quite active and see to all that for them."
http://steve-yegge.blogspot.com/2006/03/execution-in-kingdom-of-nouns.html
![Page 51: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/51.jpg)
Data types
firstlasteye-color
Person(def alex { :first "Alex" :last "Miller" :eye-color :blue })(:last alex)
(defrecord Person [first last eye-color])(def alex (Person. "Alex" "Miller" :blue))(:last alex)
![Page 52: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/52.jpg)
Polymorphism
languageProgrammer
activityNormalPerson
relax
relax
![Page 53: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/53.jpg)
Multimethods(defrecord Programmer [language])(defrecord NormalPerson [activity])
(defmulti relax class)(defmethod relax Programmer [programmer] (println "I'm writing" (:language programmer)))(defmethod relax NormalPerson [person] (println "I'm" (:activity person)))
(relax (Programmer. "Clojure"))I'm writing Clojure(relax (NormalPerson. "taking a walk"))I'm taking a walk
![Page 54: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/54.jpg)
Multimethods(defrecord Programmer [language])
(defmulti quip :language)(defmethod quip "Clojure" [programmer] (println "Running out of parens"))(defmethod quip "Java" [programmer] (println "OOP rulez!"))
(relax (Programmer. "Clojure"))Running out of parens(relax (Programmer. "Java"))OOP rulez!
![Page 55: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/55.jpg)
Protocols(defrecord Programmer [language])
(defprotocol Teacher (teach [p]) (read [p]))
(extend-type Programmer Teacher (teach [p] (println "Teaching" (:language p))) (read [p] (println "Reading Hacker News")))
(teach (Programmer. "Clojure"))Teaching Clojure
![Page 56: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/56.jpg)
State
•Immutable data is great!
•But how do I maintain state and coordinate changes?
![Page 57: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/57.jpg)
Epochal Model of Time
$120Checking
ATM-$60
$60
Time
ATM-$60
$0
State change
function
Identity
Value
![Page 58: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/58.jpg)
State Constructs•Atoms - uncoordinated synchronous change
• Like Atomic classes
•Refs - coordinated synchronous change
• STM to coordinate changes across refs
•Agents - coordinated asynchronous change
• Like actors but not "active" and state always visible to anyone
![Page 59: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/59.jpg)
Macros(defmacro and ([] true) ([x] x) ([x & next] `(let [and# ~x] (if and# (and ~@next) and#))))
![Page 60: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/60.jpg)
Macros(defmacro and ([] true) ([x] x) ([x & next] `(let [and# ~x] (if and# (and ~@next) and#))))
(and 1 2 3) (let* [i 1] (if i (let* [j 2] (if j 3 j)) i))
![Page 61: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/61.jpg)
Abstractions• functions (name and manipulate code)
• collections (trait-based, immutable collections of data)
• seq (logical lists of values)
• records (data types)
• multimethods, protocols (polymorphism)
• atoms, refs, agents (state)
• macros (syntax, order of evaluation)
• namespaces (modularity)
• metadata (out-of-band information passing)
![Page 62: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/62.jpg)
Incanter(doto (function-plot pdf-normal (add-latex 0 0.1 eq)
![Page 63: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/63.jpg)
Ring{:protocol :http :request-method :get :uri "/home" :server-name "http://example.org"}
{:status 200 :headers {"Content-Type" "text/plain" "Content Length" 11} :body "Rainbows and unicorns"}
Http request
Http response
![Page 64: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/64.jpg)
Hiccup
(html [:head [:title "My home page"]] [:body [:h1 "Links"] [:p [:a {:href "http://tech.puredanger.com"} "Alex's blog"]])
![Page 65: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/65.jpg)
Cascalog
•People in the Hadoop data set who are 25 years old(?<- (stdout) [?person] (age ?person 25))
•Split sentences to words then count words(?<- (stdout) [?word ?count] (sentence ?s) (split ?s :> ?word) (c/count ?count))
![Page 66: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/66.jpg)
10) Any sufficiently complicated C or
Fortran program contains an ad hoc,
informally-specified, bug-ridden, slow
implementation of half of Common Lisp.
Greenspun’s 10th Rule of Programming
![Page 67: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/67.jpg)
Corollaries
•Robert Morris’ corollary: “…including Common Lisp.”
•Norvig’s corollary: “Any sufficiently complicated LISP program is going to contain a slow implementation of half of Prolog”
![Page 68: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/68.jpg)
Snowclones
•Orange is the new black
•GOTO considered harmful
•Got milk ?
•I’m a doctor, not a bricklayer
![Page 69: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/69.jpg)
Snowclones
•Bacon is the new black
•Inheritance considered harmful
•Got nachos ?
•I’m a doctor, not a programmer
![Page 70: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/70.jpg)
Words for snow“If Eskimos have ___ words for snow, ___ surely have ___ words for ___.”
![Page 71: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/71.jpg)
Words for snow“If Eskimos have ___ words for snow, ___ surely have ___ words for ___.”
“If Eskimos have 100 words for snow, programmers surely have 100 words for abstraction.”
![Page 72: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/72.jpg)
Sapir-Whorf hypothesis
Do the words we have available determine what we are able to think?
![Page 73: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/73.jpg)
Do the abstractions in our language determine what
we can program?
![Page 74: Clojure: The Art of Abstraction](https://reader038.vdocuments.us/reader038/viewer/2022102816/555c25f7d8b42a0b418b4cde/html5/thumbnails/74.jpg)
Thanks!
Blog: http://tech.puredanger.com
Twitter: @puredanger
Slides: http://slideshare.com/alexmiller/presentations
Strange Loop: http://thestrangeloop.com