Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc....

214
Introduction to Clojure @stuartsierra #strangeloop 1 Sunday, September 18, 2011

Transcript of Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc....

Page 1: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Introduction toClojure

@stuartsierra#strangeloop

1Sunday, September 18, 2011

Page 2: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Bullet Points• The REPL

• Data and Code

• Working with Data

• Destructuring

• Higher-Order Functions

• Sequences

• Java Interop

• Libraries

• Namespaces

• Concurrency

• Macros

• Recursion

2Sunday, September 18, 2011

Page 3: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Stuart SierraRelevance, Inc.

Clojure/core

Clojure contributor

3Sunday, September 18, 2011

Page 4: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Where are you from?

• Lisp?

• Java / C# / C++

• ML / Haskell?

• Python / Ruby / Perl?

• Clojure?

• Multithreaded programming?

4Sunday, September 18, 2011

Page 5: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

The REPL

5Sunday, September 18, 2011

Page 6: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

The REPL

• READ

• EVALuate

• PRINT

• LOOP

6Sunday, September 18, 2011

Page 7: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

The REPL

user=> (+ 1 2 3)6user=>

"you arehere"

type anexpression press

ENTER

result

7Sunday, September 18, 2011

Page 8: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

The REPL

user=> (+ 1 2 3)6user=>

READ

EVAL

PRINT

LOOP

8Sunday, September 18, 2011

Page 9: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

The REPL

user=> (println "Hello, World!")Hello, World!nil

expression withside effects

return valueprinted output

9Sunday, September 18, 2011

Page 10: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

REPL Helpers: doc

user=> (doc when)-------------------------clojure.core/when([test & body])Macro Evaluates test. If logical true, evaluates body in an implicit do.nil

Fully-qualified name

Arguments

10Sunday, September 18, 2011

Page 11: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

REPL Helpers: find-doc

user=> (find-doc "sequence")... all definitions with "sequence" in their documentation ...nil

11Sunday, September 18, 2011

Page 12: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

REPL Helpers: apropos

user=> (apropos "map")(sorted-map ns-unmap zipmap map mapcat sorted-map-by map? amap struct-map proxy-mappings pmap map-indexed ns-map array-map hash-map)

12Sunday, September 18, 2011

Page 13: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

user=> (source take)(defn take "Returns a lazy sequence of the first n items in coll, or all items if there are fewer than n." {:added "1.0" :static true} [n coll] (lazy-seq (when (pos? n) (when-let [s (seq coll)] (cons (first s) (take (dec n) (rest s)))))))nil

REPL Helpers: source

Source code ofthe 'take' function

13Sunday, September 18, 2011

Page 14: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Data and Code

14Sunday, September 18, 2011

Page 15: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Literals

example Java type

"hello" String

\e Character

42 Long

6.022e23 Double

1.0M BigDecimal

9223372036854775808N clojure.lang.BigInt

22/7 clojure.lang.Ratio

#"hel+o" java.util.regex.Pattern

15Sunday, September 18, 2011

Page 16: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Literals

example Java type

nil null

true false Boolean

println even? + clojure.lang.Symbol

:beta ::gamma clojure.lang.Keyword

16Sunday, September 18, 2011

Page 17: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Data Structures

type example properties

list (1 2 3) singly-linked,grow at front

vector [1 2 3] indexed,grow at end

map {:a 1, :b 20} key/value pairs

set #{1 7 3} unordered, unique keys

17Sunday, September 18, 2011

Page 18: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Commas,, are,,,,,,whitespace,,,,,

18Sunday, September 18, 2011

Page 19: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Comments

;;; File-level comment

(let [x 6, y 7] ;; Block-level comment, ;; indented like code (println "Hello, World!") (* 6 7)) ; end-of-line comment

19Sunday, September 18, 2011

Page 20: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Structure

(println "Hello, World!")

listsymbol string

20Sunday, September 18, 2011

Page 21: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Semantics

(println "Hello, World!")

function call argument

function

21Sunday, September 18, 2011

Page 22: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

defn Semantics

(defn greet "Returns a friendly greeting" [your-name] (str "Hello, " your-name))

define a fndocstring

arguments

fn name

fn body

22Sunday, September 18, 2011

Page 23: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

defn Structure

(defn greet "Returns a friendly greeting" [your-name] (str "Hello, " your-name))

listsymbol

string

vector

23Sunday, September 18, 2011

Page 24: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

All forms created equalform syntax example

function list (println "hello")

"operator" list (+ 1 2)

method call list (.trim " hello ")

loading list (require 'mylib)

metadata list (with-meta obj m)

control flow list (when valid? (proceed))

scope list (let [x 5] ...)

24Sunday, September 18, 2011

Page 25: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Invocation Forms

(op ...)

• Special Form• Macro• Function

or any invocable thing• Expression which returns

an invocable thing

25Sunday, September 18, 2011

Page 26: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Invocation Forms

user=> (1 2 3)ClassCastException java.lang.Long cannot be cast to clojure.lang.IFn

26Sunday, September 18, 2011

Page 27: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Invocation Forms

user=> (1 2 3)ClassCastException java.lang.Long cannot be cast to clojure.lang.IFn

invocable things

not an invocable thing

27Sunday, September 18, 2011

Page 28: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

14 Special Forms

def if fn letloop recur do

new . throw tryset! quote var

28Sunday, September 18, 2011

Page 29: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Special Form: def

(def symbol value-expr?)

29Sunday, September 18, 2011

Page 30: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Special Form: def

user=> (def answer (* 6 7))#'user/answeruser=> answer42 Var

30Sunday, September 18, 2011

Page 31: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Special Form: if

(if condition then-expr else-expr?)

31Sunday, September 18, 2011

Page 32: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Special Form: if

user=> (if (even? 42) "even" "odd")"even"user=> (if (even? 7) "even")nil

32Sunday, September 18, 2011

Page 33: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Truthiness

Clojure Java Common Lisp

Scheme

null value

boolean values

"falsey"

"truthy"

nil null nil or ()

true / false true / false t / nil #t / #f

nil or false false nil or () #f

everything else true everything else

everything else

33Sunday, September 18, 2011

Page 34: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Special Form: do

(do exprs*)

34Sunday, September 18, 2011

Page 35: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Special Form: do

user=> (do 1 2 3)3user=> (do (println 42 "is even") 42)42 is even42

35Sunday, September 18, 2011

Page 36: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Special Form: do

user=> (if (even? 42) (do (println 42 "is even") 42)))42 is even42

36Sunday, September 18, 2011

Page 37: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Macro: when

(when condition exprs*)

(if condition (do exprs*))

37Sunday, September 18, 2011

Page 38: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Macro: when

user=> (when (even? 42) (println 42 "is even") 42)42 is even42

38Sunday, September 18, 2011

Page 39: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Special Form: quote

(quote form)

'form

39Sunday, September 18, 2011

Page 40: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Special Form: quote

user=> (1 2 3)ClassCastException java.lang.Long cannot be cast to clojure.lang.IFn

user=> (quote (1 2 3))(1 2 3)user=> '(1 2 3)(1 2 3)user=> (list 1 2 3)(1 2 3)

40Sunday, September 18, 2011

Page 41: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Special Form: let

(let [bindings*] exprs*)

41Sunday, September 18, 2011

Page 42: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Special Form: let

user=> (let [x 6, y 7] (* x y))42

Binding forms

Value expressions

42Sunday, September 18, 2011

Page 43: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Special Form: let

user=> (let [x 6 y (+ x 1)] (* x y))42

Earlier bindingsavailable

43Sunday, September 18, 2011

Page 44: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Special Form: let

user=> (let [x 6 y (+ x 1)] (println (* x y)) (let [y 10] (println (* x y))))4260nil Rebinding is allowed

44Sunday, September 18, 2011

Page 45: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Special Form: let

user=> (let [x 5] (let [y x] (let [y y] (let [z (+ x y)] z))))

45Sunday, September 18, 2011

Page 46: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Special Form: fn

(fn [params*] exprs*)

(fn ([params*] exprs*)+)

46Sunday, September 18, 2011

Page 47: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Special Form: fn

user=> (fn [x] (+ x 5))#<user$eval1456$fn__1457>user=> (def add5 (fn [x] (+ x 5)))#'user/add5user=> (add5 10)15

compiled fn

47Sunday, September 18, 2011

Page 48: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Macro: defn

(defn symbol [params*] exprs*)

(def symbol (fn [params*] exprs*))

48Sunday, September 18, 2011

Page 49: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Arity

user=> (defn greet ([] (greet "Clojure" "programmer")) ([name] (greet name "the programmer")) ([first-name last-name] (println "Hello," first-name last-name)))#'user/greetuser=> (greet)Hello, Clojure programmerniluser=> (greet "Stuart")Hello, Stuart the programmerniluser=> (greet "Stuart" "Sierra")Hello, Stuart Sierranil

49Sunday, September 18, 2011

Page 50: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Variadic

user=> (defn greet ([name] (println "Hello," name)) ([name & others] (println "Hello," name "and friends" others)))#'user/greetuser=> (greet "Stuart")Hello, Stuartniluser=> (greet "Stuart" "Aaron" "Fogus" "Chouser")Hello, Stuart and friends (Aaron Fogus Chouser)nil

50Sunday, September 18, 2011

Page 51: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Working with Data

51Sunday, September 18, 2011

Page 52: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Value Equality

user=> (= [1 2 3] [1 2 3])trueuser=> (= [1 2 3] [1.0 2.0 3.0])trueuser=> (= [1 2 3] '(1 2 3))true

52Sunday, September 18, 2011

Page 53: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Reference Equality

user=> (= (StringBuilder. "a") (StringBuilder. "a"))false user=> (identical? [1 2 3] [1 2 3])falseuser=> (identical? 2.0 2)false

53Sunday, September 18, 2011

Page 54: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Reference Equality

user=> (= :a :a)true user=> (identical? :a :a)trueuser=> (= 'a 'a)trueuser=> (identical? 'a 'a)false

54Sunday, September 18, 2011

Page 55: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Collections

user=> (count [:a :b :c])3user=> (coll? [:a :b :c])trueuser=> (vector? [:a :b :c])trueuser=> (list? [:a :b :c])false

55Sunday, September 18, 2011

Page 56: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

• List

• Vector

Sequential Things

56Sunday, September 18, 2011

Page 57: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Sequential Things

user=> (def v [:a :b :c :d])#'user/vuser=> (first v):auser=> (second v):buser=> (def w (vector 10 11 12 13))#'user/wuser=> (nth w 3)13

57Sunday, September 18, 2011

Page 58: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

conj

user=> (def v [:a :b :c :d])#'user/vuser=> (conj v :more)[:a :b :c :d :more]

user=> (def lst (list 1 2 3 4))#'user/lstuser=> (conj lst :more)(:more 1 2 3 4)

Vectors growat the end

Lists growat the front

58Sunday, September 18, 2011

Page 59: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Associative Things

• Map

• Hash map

• Array map

• Vector (sometimes)

59Sunday, September 18, 2011

Page 60: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Maps: get

user=> (def m {:a 1 :b 2})#'user/muser=> (get m :a)1user=> (m :a)1user=> (:a m)1

Maps areinvocable

So are keywords

60Sunday, September 18, 2011

Page 61: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Maps: assoc

user=> (def m (hash-map :a 1 :b 2))#'user/muser=> (assoc m :c 3 :d 4){:a 1, :c 3, :b 2, :d 4}user=> (assoc m :a 17){:a 17, :b 2} new map

with addedkey-value pairs

61Sunday, September 18, 2011

Page 62: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Maps

user=> (def m {:a 1 :b 2})#'user/muser=> (dissoc m :a){:b 2}user=> (keys m)(:a :b)user=> (conj m [:c 3]){:a 1, :c 3, :b 2}

conj on a maptakes a vector pair

62Sunday, September 18, 2011

Page 63: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Maps: merge

user=> (def m {:a 1 :b 2})#'user/muser=> (merge m {:b 17 :c 22}){:a 1, :c 22, :b 17}

63Sunday, September 18, 2011

Page 64: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Maps: zipmap

user=> (zipmap [:a :b :c] [1 2 3]){:c 3, :b 2, :a 1}

64Sunday, September 18, 2011

Page 65: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Maps: get-in

user=> (def person {:name {:first "Stuart" :last "Sierra"} :address {:city "Brooklyn" :state "New York"}})#'user/personuser=> (:first (:name person))"Stuart"user=> (get-in person [:name :first])"Stuart"

65Sunday, September 18, 2011

Page 66: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Maps: assoc-in

user=> (def person {:name {:first "Stuart" :last "Sierra"} :address {:city "Brooklyn" :state "New York"}})#'user/personuser=> (assoc-in person [:name :last] "Halloway"){:name {:last "Halloway", :first "Stuart"}, :address {:state "New York", :city "Brooklyn"}}

66Sunday, September 18, 2011

Page 67: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Vectors are Associative

user=> (def v [:a :b :c])#'user/vuser=> (assoc v 1 "Hello")[:a "Hello" :c]

67Sunday, September 18, 2011

Page 68: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Sets

user=> (def s #{1 2 3})#'user/suser=> s#{1 2 3}user=> (conj s 17)#{1 2 3 17}user=> (conj s 2)#{1 2 3}

68Sunday, September 18, 2011

Page 69: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Sets

user=> (def v [1 2 3 1 2 3 4])#'user/vuser=> (set v)#{1 2 3 4}

69Sunday, September 18, 2011

Page 70: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Sets: contains?

user=> (def s #{1 2 3})#'user/suser=> (contains? s 3)trueuser=> (contains? s 17)false

Checks keys,not values

70Sunday, September 18, 2011

Page 71: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Sets: invocation

user=> (def s #{1 2 3})#'user/suser=> (s 3)3user=> (s 17)nil

Returns objectif it's in the set

71Sunday, September 18, 2011

Page 72: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Destructuring

72Sunday, September 18, 2011

Page 73: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Destructuring

user=> (def stuff [7 8 9 10])#'user/stuff

user=> (let [[a b c d] stuff] (list (+ a b) (+ c d))) (15 19)

73Sunday, September 18, 2011

Page 74: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Destructuring

(let [bindings*] exprs*)

74Sunday, September 18, 2011

Page 75: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Destructuring

(let [binding-form value-expr] exprs*)

75Sunday, September 18, 2011

Page 76: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Sequential Destructuring

(let [[a b c d] stuff] exprs*)

Binding form Value expression

76Sunday, September 18, 2011

Page 77: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

(let [[a b c d] stuff] ...

(let [[a b c d] [7 8 9 10]] ...Evaluate

(let [a 7 b 8 c 9 d 10] ...

Destructure

Sequential Destructuring

77Sunday, September 18, 2011

Page 78: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

user=> (def stuff [7 8 9 10])#'user/stuff

user=> (let [[a & others] stuff] (println a) (println others))7(8 9 10)nil

Sequential Destructuring

78Sunday, September 18, 2011

Page 79: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

(let [[symbols+ & symbol] expr] exprs*)

Get the first one or more elements

Get all remaining elements

Sequential Destructuring

79Sunday, September 18, 2011

Page 80: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Associative Destructuring

user=> (def m {:a 7 :b 4})#'user/muser=> (let [{a :a, b :b} m] [a b])[7 4]

80Sunday, September 18, 2011

Page 81: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

user=> (def m {:a 7 :b 4})#'user/muser=> (let [{:keys [a b]} m] [a b])[7 4]

Associative Destructuring

81Sunday, September 18, 2011

Page 82: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Keyword Destructuring

user=> (def m {:a 7 :b 4})#'user/muser=> (let [{:keys [a b c]} m] [a b c])[7 4 nil]

82Sunday, September 18, 2011

Page 83: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Destructuring with Default Values

user=> (def m {:a 7 :b 4})#'user/muser=> (let [{:keys [a b c] :or {c 3}} m] [a b c])[7 4 3]

83Sunday, September 18, 2011

Page 84: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Destructuring

(fn [params*] exprs*)

(defn symbol [params*] exprs*)

Destructuringworks here too

84Sunday, September 18, 2011

Page 85: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Nested Destructuring

user=> (def data {:a [1 2 3] :b {:c 4}})#'user/data

user=> (let [{[x & y] :a {:keys [c d] :or {d 10}} :b} data] (+ x c d))

???

85Sunday, September 18, 2011

Page 86: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Higher-Order Functions

86Sunday, September 18, 2011

Page 87: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

apply

user=> (def v [1 2 3 4])#'user/vuser=> (println v)[1 2 3 4]niluser=> (apply println v)1 2 3 4niluser=> (println 1 2 3 4)1 2 3 4nil

87Sunday, September 18, 2011

Page 88: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

map

user=> (def v [1 2 3 4])#'user/vuser=> (map (fn [x] (* 5 x)) v)(5 10 15 20)

88Sunday, September 18, 2011

Page 89: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

#() syntax

user=> (map (fn [x] (* 5 x)) v)(5 10 15 20)user=> (map #(* 5 %) v)(5 10 15 20) Same fn

89Sunday, September 18, 2011

Page 90: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

map

user=> (def v [:a :b :c])#'user/vuser=> (def w [10 20 30 40 50])#'user/nuser=> (map vector v w)([:a 10] [:b 20] [:c 30])

90Sunday, September 18, 2011

Page 91: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

reduce

user=> (reduce + [1 2 3 4])10user=> (+ (+ (+ 1 2) 3) 4)10

91Sunday, September 18, 2011

Page 92: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

reduce

user=> (reduce + 100 [1 2 3 4])110user=> (+ (+ (+ (+ 100 1) 2) 3) 4)110

seed value

92Sunday, September 18, 2011

Page 93: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

reduce

user=> (reduce (fn [m [k v]] (assoc m (name k) (+ 100 v))) {} {:a 1 :b 2}){"b" 102, "a" 101}

destructurekey-value pair

seed value

93Sunday, September 18, 2011

Page 94: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

filter and remove

user=> (filter even? [1 2 3 4 5])(2 4)user=> (filter (set "aeiou") "Hello, World!")(\e \o \o)user=> (apply str (remove (set "aeiou") "Hello, World!"))"Hll, Wrld!"

94Sunday, September 18, 2011

Page 95: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Maps: assoc-in

user=> (def person {:name {:first "Stuart" :last "Sierra"} :address {:city "Brooklyn" :state "New York"}})#'user/personuser=> (assoc-in person [:name :last] "Halloway"){:name {:last "Halloway", :first "Stuart"}, :address {:state "New York", :city "Brooklyn"}}

95Sunday, September 18, 2011

Page 96: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Maps: update-in

user=> (def person {:name {:first "Stuart" :last "Sierra"} :address {:city "Brooklyn" :state "New York"}})#'user/personuser=> (update-in person [:name :last] #(.toUpperCase %)){:name {:last "SIERRA", :first "Stuart"}, :address {:state "New York", :city "Brooklyn"}}

96Sunday, September 18, 2011

Page 97: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

identity

user=> (doc identity)-------------------------clojure.core/identity([x]) Returns its argument.nil

97Sunday, September 18, 2011

Page 98: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

filter and identity

user=> (def v [1 2 3 nil 4 5 nil 6])#'user/vuser=> (filter identity v)(1 2 3 4 5 6)

98Sunday, September 18, 2011

Page 99: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

fnil

user=> (doc fnil)-------------------------clojure.core/fnil([f x] [f x y] [f x y z]) Takes a function f, and returns a function that calls f, replacing a nil first argument to f with the supplied value x.

99Sunday, September 18, 2011

Page 100: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

fnil

user=> (+ nil 3)NullPointerException clojure.lang.Numbers.opsuser=> (def add (fnil + 0))#'user/adduser=> (add nil 3)3

100Sunday, September 18, 2011

Page 101: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

update-in and fnil

user=> (def m {:foo {:a 1 :b 2} :bar {:c 3}})#'user/muser=> (update-in m [:foo :a] inc){:foo {:a 2, :b 2}, :bar {:c 3}}user=> (update-in m [:baz :d] inc)NullPointerException clojure.lang.Numbers.opsuser=> (update-in m [:baz :d] (fnil inc 0)){:foo {:a 1, :b 2}, :bar {:c 3}, :baz {:d 1}}

101Sunday, September 18, 2011

Page 102: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

frequencies

user=> (reduce (fn [m c] (update-in m [c] (fnil inc 0))) {} "a short sharp shock"){\space 3, \a 2, \c 1, \h 3, \k 1, \o 2, \p 1, \r 2, \s 3, \t 1}

user=> (frequencies "a short sharp shock"){\space 3, \a 2, \c 1, \h 3, \k 1, \o 2, \p 1, \r 2, \s 3, \t 1}

102Sunday, September 18, 2011

Page 103: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Sequences

103Sunday, September 18, 2011

Page 104: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Lists

first next first next first next

lst

nil

(def lst '(1 2 3))

1 2 3

104Sunday, September 18, 2011

Page 105: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Sequences

lst

(def lst (range 1 4))#'user/lst

LazySeq

fn

105Sunday, September 18, 2011

Page 106: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Sequences

lst

(first lst)1

LazySeq

first next

1

LazySeq

fn

106Sunday, September 18, 2011

Page 107: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Sequences

lst

(second lst)2

LazySeq

first next

1

LazySeq

first next

2

LazySeq

fn

107Sunday, September 18, 2011

Page 108: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

range

(range)

(range end)

(range start end)

(range start end step)

infinite!

108Sunday, September 18, 2011

Page 109: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Infinite Sequences

user=> (map vector (range) [:a :b :c])([0 :a] [1 :b] [2 :c])

user=> (map-indexed vector [:a :b :c])([0 :a] [1 :b] [2 :c])

user=> (zipmap "abc" (range)){\c 2, \b 1, \a 0}

109Sunday, September 18, 2011

Page 110: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

repeat

user=> (repeat 5 :a)(:a :a :a :a :a)

user=> (take 10 (repeat :b))(:b :b :b :b :b :b :b :b :b :b)

infinite!

110Sunday, September 18, 2011

Page 111: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

seq

user=> (seq [1 2 3])(1 2 3)user=> (seq {:a 1 :b 2 :c 3})([:a 1] [:c 3] [:b 2])user=> (seq #{1 2 3})(1 2 3)user=> (seq [])nil

111Sunday, September 18, 2011

Page 112: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Lazy vs. Strict

(with-open [file ...] (line-seq file))

returns lazy seqof lines in file

file is closed here

112Sunday, September 18, 2011

Page 113: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Lazy vs. Strict

(with-open [file ...] (doall (line-seq file))

force entire seqto be realized

113Sunday, September 18, 2011

Page 114: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

doall, dorun, doseq

(doall sequence)

(dorun sequence)

(doseq [symbol sequence] ...body...)

returns sequence

returns nil

returns nil

114Sunday, September 18, 2011

Page 115: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Java Interop

115Sunday, September 18, 2011

Page 116: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Java Types

Clojure Literal Java Type

"hello" java.lang.String

3.14 java.lang.Double

[1 2 3] java.util.List

{"a" 1, "b" 2} java.util.Map

(fn [x] (* x 5)) java.lang.Runnable

116Sunday, September 18, 2011

Page 117: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

class and ancestors

user=> (class "hello")java.lang.Stringuser=> (ancestors (class "hello"))#{java.lang.CharSequence java.lang.Comparable java.lang.Object java.io.Serializable}

117Sunday, September 18, 2011

Page 118: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

REPL Helpers: javadoc

user=> (javadoc java.io.Writer)"http://java.sun.com/javase/6/docs/api/java/io/Writer.html"

user=> (javadoc "hello")"http://java.sun.com/javase/6/docs/api/java/lang/String.html"

Java class

Object

118Sunday, September 18, 2011

Page 119: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Special Form: . (dot)

(. object method arguments*)

(. object field)

(. class static-method arguments*)

(. class static-field)

119Sunday, September 18, 2011

Page 120: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Instance Method Calls

user=> (. "hello" charAt 0)\h

user=> (.charAt "hello" 0)\h

Syntactic sugar

object method arguments

120Sunday, September 18, 2011

Page 121: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Static Method Calls

user=> (. Long valueOf "42")42

user=> (Long/valueOf "42")42

Syntactic sugar

121Sunday, September 18, 2011

Page 122: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Static Fields

user=> (. Math PI)3.141592653589793

user=> Math/PI3.141592653589793

Syntactic sugar

122Sunday, September 18, 2011

Page 123: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Constructors

user=> (new java.io.File "/home")#<File /home>

user=> (java.io.File. "/home")#<File /home>

Syntactic sugar

Constructorargumentsclass name

123Sunday, September 18, 2011

Page 124: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Java Import

user=> (import (java.net URL URI))java.net.URIuser=> (URL. "http://clojure.org/")#<URL http://clojure.org/>

Package Classes"prefix list"

124Sunday, September 18, 2011

Page 125: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

try/catch/finally

(try ... expressions ... (catch Class name ... handle exception ...) (finally ... always do this ...))

125Sunday, September 18, 2011

Page 126: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

throw

(throw exception)

126Sunday, September 18, 2011

Page 127: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

throw and *e

user=> (throw (Exception. "Boom!"))Exception Boom! user/eval11 (NO_SOURCE_FILE:5)user=> *e#<RuntimeException java.lang.RuntimeException: java.lang.Exception: Boom!>

constructor

127Sunday, September 18, 2011

Page 128: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

print stack trace

user=> (pst)Exception Boom! user/eval11 (NO_SOURCE_FILE:5) clojure.lang.Compiler.eval (Compiler.java:6424) clojure.lang.Compiler.eval (Compiler.java:6390) clojure.core/eval (core.clj:2795) clojure.main/repl/read-eval-print--5967 (main.clj:244)

defined in clojure.repl

128Sunday, September 18, 2011

Page 129: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Java Interop Summary

Special Form Sugar

Instance Method

Instance Field

Static Method

Static Field

Constructor

(. obj method args*) (.method obj args*)

(. obj field) (.field obj)

(. Class method args*) (Class/method args*)

(. Class field) Class/field

(new Class args*) (Class. args*)

129Sunday, September 18, 2011

Page 130: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Java Nested Classes

Package-QualifiedClass Name

UnqualifiedClass Name

Regular Class

Inner Class

java.io.File File

java.util.Map$Entry Map$Entry

130Sunday, September 18, 2011

Page 131: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Libraries

131Sunday, September 18, 2011

Page 132: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Java Classpath

Clojure source code in ./src/JAR files in ./lib/

java -cp src:lib/* clojure.main

classpath

132Sunday, September 18, 2011

Page 133: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Project Management

• Leiningen

• Cake

• Maven

• Ant

133Sunday, September 18, 2011

Page 134: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

MavenDirectory Structure

pom.xmlsrc/main/clojure/ your/project/file.cljsrc/test/clojure/ your/project/file_test.cljtarget/classes/ compiled_file.class$HOME/.m2/repository/ org/clojure/clojure/1.3.0/clojure-1.3.0.jar

134Sunday, September 18, 2011

Page 135: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

LeiningenDirectory Structure

project.cljsrc/ your/project/file.cljtest/ your/project/file_test.cljclasses/ compiled_file.classlib/ clojure-1.3.0.jar

135Sunday, September 18, 2011

Page 136: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Leiningen project.clj

(defproject my.project.name "1.0.0" :description "My cool Clojure project." :dependencies [[org.clojure/clojure "1.3.0"] [org.clojure/data.zip "0.1.0"]])

groupId artifactId version

136Sunday, September 18, 2011

Page 137: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Leiningen Commands$ lein helpLeiningen is a build tool for Clojure.

Several tasks are available: pom help jar test deps ... repl new

Run lein help $TASK for details.See http://github.com/technomancy/leiningen as well.

137Sunday, September 18, 2011

Page 138: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Finding Dependencies

• search.maven.org

• jarvana.com

• clojars.org

138Sunday, September 18, 2011

Page 139: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

clojure-contribup to 1.2

• One big library

• Version number matches Clojure

• Mixed quality

Clojureclojure-contrib

1.0.0 1.0.0

1.1.0 1.1.0

1.2.01.2.1 1.2.0

139Sunday, September 18, 2011

Page 140: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

clojure-contribafter 1.2

• Many small libraries

• Independent version numbers

• Compatible withClojure 1.2 and 1.3

• Mixed quality

algo.monadscore.incubator

core.logiccore.match

core.unifydata.csv

data.finger-treedata.json

data.priority-mapdata.xmldata.zip

java.classpathjava.datajava.jdbcjava.jmx

math.combinatoricsmath.numeric-tower

test.generativetools.cli

tools.loggingtools.macro

tools.namespacetools.nrepltools.tracedev.clojure.org/display/doc/Clojure+Contrib

140Sunday, September 18, 2011

Page 141: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Included in Clojure• clojure.inspector

• clojure.java.io

• clojure.java.browse

• clojure.java.shell

• clojure.reflect

• clojure.repl

• clojure.string

• clojure.set

• clojure.test

• clojure.walk

• clojure.xml

• clojure.zip

141Sunday, September 18, 2011

Page 142: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Namespaces

142Sunday, September 18, 2011

Page 143: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

The REPL

user=> (+ 1 2 3)6user=>

"you arehere"

143Sunday, September 18, 2011

Page 144: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Namespaces

user=> (ns my.cool.thing)nilmy.cool.thing=>

"you are here"

144Sunday, September 18, 2011

Page 145: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Qualified Symbols

user=> (ns foo.bar)nilfoo.bar=> (defn hello [] (println "Hello, World!"))#'foo.bar/hellofoo.bar=> (ns baz.quux)nilbaz.quux=> (foo.bar/hello)Hello, World!nil

Namespace-qualifiedsymbol

145Sunday, September 18, 2011

Page 146: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Namespaces and Files

$CLASSPATH/my/cool/thing.clj

(ns my.cool.thing)

dots become slashes

146Sunday, September 18, 2011

Page 147: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Names and Hyphens

$CLASSPATH/my/cool/web_app.clj

(ns my.cool.web-app)

hyphens become underscores

147Sunday, September 18, 2011

Page 148: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Macro: ns

(ns name references*)

148Sunday, September 18, 2011

Page 149: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

ns :require

(ns my.cool.project (:require [some.ns.foo :as foo]))

(foo/function-in-foo)

ns alias

149Sunday, September 18, 2011

Page 150: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

ns :use

(ns my.cool.project (:use [some.ns.foo :only (a b)]))

(a)(b) list of

symbols

unqualifiedsymbols

150Sunday, September 18, 2011

Page 151: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

ns :use

(ns my.cool.project (:use some.ns.foo))

(a)(b)

unqualified symbolsfrom anywhere

151Sunday, September 18, 2011

Page 152: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

ns :import

(ns my.cool.project (:import (java.io File Writer))

packagename

classnames

152Sunday, September 18, 2011

Page 153: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Macro: ns

(ns name (:require [some.ns.foo :as foo] [other.ns.bar :as bar]) (:use [this.ns.baz :only (a b c)] [that.ns.quux :only (d e f)]) (:import (java.io File FileWriter) (java.net URL URI))

153Sunday, September 18, 2011

Page 154: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

require in the REPL

user=> (require '[clojure.set :as set])niluser=> (set/union #{1 2} #{2 3 4})#{1 2 3 4}

arguments mustbe quoted

154Sunday, September 18, 2011

Page 155: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

use in the REPL

user=> (use 'clojure.string)WARNING: replace already refers to: #'clojure.core/replace in namespace: user, being replaced by: #'clojure.string/replaceWARNING: reverse already refers to: #'clojure.core/reverse in namespace: user, being replaced by: #'clojure.string/reverseniluser=> (reverse "hello")"olleh"

arguments mustbe quoted

155Sunday, September 18, 2011

Page 156: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

RELP Helpers: dir

user=> (dir clojure.repl)aproposdemungedirdir-fndocfind-docpstroot-causeset-break-handler!sourcesource-fnstack-element-strthread-stoppernil

156Sunday, September 18, 2011

Page 157: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Concurrency

157Sunday, September 18, 2011

Page 158: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Concurrency

Parallelism

State

158Sunday, September 18, 2011

Page 159: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

class Invoice { private Date date;

public Date getDate() { return this.date; }

public void setDate(Date date) { this.date = date; }}

159Sunday, September 18, 2011

Page 160: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

class Date { public void setDay(int day); public void setMonth(int month); public void setYear(int year);}

Mutable!

160Sunday, September 18, 2011

Page 161: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

class Invoice { private Date date;

public Date getDate() { return this.date; }

public void setDate(Date date) { this.date = date; }}

Better notchange it!

Better notchange it!

161Sunday, September 18, 2011

Page 162: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

class Invoice { private Date date;

public Date getDate() { return this.date.clone(); }

public void setDate(Date date) { this.date = date.clone(); }}

Defensivecopying

162Sunday, September 18, 2011

Page 163: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Programming with immutable values

means never having to say you're sorry.

163Sunday, September 18, 2011

Page 164: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Sept 18

today

164Sunday, September 18, 2011

Page 165: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Sept 18 Sept 19

today

165Sunday, September 18, 2011

Page 166: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Sept 18

Identity

State

Sept 19

today

Value Value

166Sunday, September 18, 2011

Page 167: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Sept 18

Identity

State

Sept 19

today

function

Value Value

function

167Sunday, September 18, 2011

Page 168: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Sept 18

Identity

State

Past

Sept 19Sept 17 function

Present Future

function

today

168Sunday, September 18, 2011

Page 169: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Sept 18

Identity

State

Past

Sept 19Sept 17 function

Present Future

function

today

The future is a function of the past.

169Sunday, September 18, 2011

Page 170: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Mutable References

Ref Atom

Var Agent

170Sunday, September 18, 2011

Page 171: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

readers

Atomwriter

writer

abortretry

171Sunday, September 18, 2011

Page 172: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Atom(def tick (atom 1))(deref tick) 1

tick

1

172Sunday, September 18, 2011

Page 173: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Atom(def tick (atom 1))(deref tick) 1

(swap! tick inc)@tick 2

tick

1

2

inc

173Sunday, September 18, 2011

Page 174: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Atom(def tick (atom 1))(deref tick) 1

(swap! tick inc)@tick 2

(swap! tick + 10)@tick 12

tick

2

12

+10

174Sunday, September 18, 2011

Page 175: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

value value value value

value value value value

value value value value

identity

identityidentity

175Sunday, September 18, 2011

Page 176: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

value value value value

value value value value

value value value value

identity

identityidentity

176Sunday, September 18, 2011

Page 177: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Refwriter

writer

readers

abortretryRef

transaction

177Sunday, September 18, 2011

Page 178: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Ref(def A (ref 1))(def B (ref 10))

A 1

10B

178Sunday, September 18, 2011

Page 179: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Ref(def A (ref 1))(def B (ref 10))

(dosync (alter A inc) (alter B + 10))

A 1

10

20

inc

+10

B

2

transaction

179Sunday, September 18, 2011

Page 180: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Ref(def A (ref 1))(def B (ref 10))

(dosync (alter A inc) (alter B + 10))

A

20

B

2

@A 2@B 20

180Sunday, September 18, 2011

Page 181: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

AtomicConsistentIsolatedDurable

Database Transactions

181Sunday, September 18, 2011

Page 182: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

AtomicConsistentIsolated

Clojure Transactions

182Sunday, September 18, 2011

Page 183: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Agentactionaction

readers

action queue

Agent Thread Pool

183Sunday, September 18, 2011

Page 184: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Agent(def A (agent 1))

A 1queue

184Sunday, September 18, 2011

Page 185: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Agent(def A (agent 1))

(send A inc)@A 1

A 1inc

queue

185Sunday, September 18, 2011

Page 186: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Agent(def A (agent 1))

(send A inc)@A 1

A 1inc

2@A 2

queue

186Sunday, September 18, 2011

Page 187: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Varroot

binding

thread-local

binding

thread-local

binding

other threads

187Sunday, September 18, 2011

Page 188: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Ref Atom

Var Agent

Concurrency

188Sunday, September 18, 2011

Page 189: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Macros

189Sunday, September 18, 2011

Page 190: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

You

Lexer/Parser

Characters

AbstractSyntax Tree

Compiler/Interpreter

190Sunday, September 18, 2011

Page 191: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Clojure Reader

ClojureCompiler

You Characters

Data Structures

191Sunday, September 18, 2011

Page 192: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Clojure Reader

You Characters

Data Structures

Macros

ClojureCompiler

192Sunday, September 18, 2011

Page 193: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

read-string and eval

user=> (read-string "(println 1 2 3)")(println 1 2 3)

user=> (eval *1)1 2 3nil

193Sunday, September 18, 2011

Page 194: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Macro: when

(when condition exprs*)

(if condition (do exprs*))

194Sunday, September 18, 2011

Page 195: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

defmacro

(defmacro when [test & body] (list 'if test (cons 'do body)))

name parameters

construct codeto return

195Sunday, September 18, 2011

Page 196: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

macroexpand

user=> (macroexpand '(when a b c d))(if a (do b c d))

quoted expression

expanded result

196Sunday, September 18, 2011

Page 197: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

How to Write a Macro

Form you want to write

Form you wantit to become

functioninput output

197Sunday, September 18, 2011

Page 198: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

How to Write a Macro

;; we want to write: ;; and have it become:(when foo (if foo (dothis) (do (dothat)) (dothis) (dothat))) ;; from core.clj(defmacro when [test & body] (list 'if test (cons 'do body)))

;; use macroexpand to try ituser=> (macroexpand '(when foo (dothis) (dothat)))(if foo (do (dothis) (dothat)))

198Sunday, September 18, 2011

Page 199: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Macro Expansion

(when a b c d)

Macro: when

(if a (do b c d))

arguments arenot evaluated

199Sunday, September 18, 2011

Page 200: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

syntax-quote

(defmacro when [test & body] `(if ~test (do ~@body)))

syntax-quote unquote splicingunquote

200Sunday, September 18, 2011

Page 201: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

syntax-quote

user=> (def x 5)#'user/xuser=> (def lst '(:a :b :c))#'user/lstuser=> `(x ~x ~lst)(user/x 5 (:a :b :c))user=> `(x ~x ~@lst)(user/x 5 :a :b :c)

201Sunday, September 18, 2011

Page 202: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

gensym

user=> (gensym "foo")foo39user=> (gensym "foo")foo42

202Sunday, September 18, 2011

Page 203: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

user=> `(let [x 1] x)(clojure.core/let [user/x 1] user/x)

user=> `(let [x# 1] x#)(clojure.core/let [x__29__auto__ 1] x__29__auto__)

generatedsymbol

auto-gensymqualified symbolnot allowed here

203Sunday, September 18, 2011

Page 204: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Recursion

204Sunday, September 18, 2011

Page 205: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Recursive GCD

user=> (defn gcd [x y] ; x >= y (if (zero? y) x (gcd y (rem x y))))#'user/gcduser=> (gcd 100 35)5user=> (gcd 37 22)1

205Sunday, September 18, 2011

Page 206: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Recursive GCD

user=> (defn gcd [x y] ; x >= y (if (zero? y) x (gcd y (rem x y))))

tail position

206Sunday, September 18, 2011

Page 207: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

GCD with recur

user=> (defn gcd [x y] ; x >= y (if (zero? y) x (recur y (rem x y))))

tail position

207Sunday, September 18, 2011

Page 208: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Recursive Fibonacci

user=> (defn fib [n] (cond (zero? n) 0 (= 1 n) 1 :else (+ (fib (dec n)) (fib (- n 2)))))#'user/fibuser=> (fib 10)55user=> (fib 50) ; wait a really long time

208Sunday, September 18, 2011

Page 209: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Fibaonacci Helper

user=> (defn fib-step [a b n] (if (= 1 n) b (recur b (+ a b) (dec n))))#'user/fib-stepuser=> (defn fib [n] (fib-step 0 1 n))#'user/fibuser=> (fib 50)12586269025

209Sunday, September 18, 2011

Page 210: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

loop / recur

user=> (defn fib [n] (loop [a 0, b 1, i n] (if (= 1 i) b (recur b (+ a b) (dec i)))))#'user/fibuser=> (fib 50)12586269025

210Sunday, September 18, 2011

Page 211: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

loop / recur

(loop [initialization] (if termination-condition return-value (recur updated-variables)))

211Sunday, September 18, 2011

Page 212: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

More

212Sunday, September 18, 2011

Page 213: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Clojure

• clojure.org

• clojure.blip.tv

• dev.clojure.org

• groups.google.com/group/clojure

• #clojure on irc.freenode.net

213Sunday, September 18, 2011

Page 214: Introduction to Clojure - Digital Digressions by Stuart … · Stuart Sierra Relevance, Inc. Clojure/core Clojure contributor Sunday, September 18, 2011 3

Fun

• github.com/relevance/labrepl

• 4clojure.com

• github.com/functional-koans/clojure-koans

214Sunday, September 18, 2011