Http://Github.com/Stuarthalloway/Clojure Presentations

Post on 30-May-2018

213 views 0 download

Transcript of Http://Github.com/Stuarthalloway/Clojure Presentations

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 1/152

Copyright 2007-2009 Relevance, Inc. This presentation is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License. See http://creativecommons.org/licenses/by-nc-sa/3.0/us/

stuart halloway

1

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 2/152

clojure’s four elevators java interop

lisp

functionalstate

2

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 3/152

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 4/152

java new

java new Widget( "foo" )

clojure ( new Widget "foo" )

clojure sugar (Widget . "red" )

4

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 5/152

access static members

java Math.PI

clojure (. Math PI)

clojure sugar Math/PI

5

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 6/152

access instance members

java rnd.nextInt()

clojure (. rnd nextInt)

clojure sugar (.nextInt rnd)

6

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 7/152

chaining access

java person.getAddress().getZipCode()

clojure (. (. person getAddress) getZipCode)

clojure sugar (.. person getAddress getZipCode)

7

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 8/152

parenthesis count

java ()()()()

clojure ()()()

8

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 9/152

atomic data typestype example java equivalentstring "foo" String

character \f Character

regex #"fo*" Pattern

a. p. integer 42 Integer/Long/BigInteger

double 3.14159 Double

a.p. double 3.14159M BigDecimal

boolean TRUE Booleannil nil null

symbol foo, + N/A

keyword :foo, ::foo N/A9

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 10/152

example:refactor apache

commons isBlank 10

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 11/152

public class StringUtils {public static boolean isBlank( String str) {

int strLen;if (str == null || (strLen = str.length()) == 0 ) {

return true ;}for (int i = 0 ; i < strLen; i ++) {

if (( Character .isWhitespace(str.charAt(i)) == false )) {return false ;

}}

return true ;}

}

initial implementation

11

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 12/152

public class StringUtils {public isBlank(str) {

if (str == null || (strLen = str.length()) == 0 ) {return true ;

}

for (i = 0 ; i < strLen; i ++) {if (( Character .isWhitespace(str.charAt(i)) == false )) {

return false ;}

} return true ;

}}

- type decls

12

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 13/152

public isBlank(str) {if (str == null || (strLen = str.length()) == 0 ) {

return true ;}

for (i = 0 ; i < strLen; i ++) {if (( Character .isWhitespace(str.charAt(i)) == false )) {

return false ;}

} return true ;}

- class

13

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 14/152

public isBlank(str) {if (str == null || (strLen = str.length()) == 0 ) {

return true ;}every (ch in str) {

Character .isWhitespace(ch);}

return true ;}

+ higher-order function

14

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 15/152

public isBlank(str) {

every (ch in str) {Character .isWhitespace(ch);

}}

- corner cases

15

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 16/152

( defn blank? [ s ] ( every? #(Character/isWhitespace %) s))

lispify

16

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 17/152

clojure is a better java than java

17

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 18/152

2. lisp

18

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 19/152

what makes lisp different

http://www.paulgraham.com/diff.html

feature industrynorm

coolkids clojure

conditionals

variables

garbage collection

recursion

function type

symbol type

whole language available

everything’s an expressionhomoiconicity

19

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 20/152

foo.bar(x,y,z);

foo.bar x y z

regular code

20

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 21/152

special formsimports

scopes

protection

metadata

control ow

anything using a keyword

21

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 22/152

outside lisp, special formslook different

may have special semantics unavailable to you

prevent reuse

22

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 23/152

in a lisp, special formslook just like anything else

may have special semantics available to you

can be augmented with macros

23

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 24/152

all forms created equal

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 ow list (when valid? (proceed))

scope list (dosync (alter ...))

24

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 25/152

who cares?

25

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 26/152

26

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 27/152

clojure is turning

the tide in a fty-year struggleagainst bloat

27

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 28/152

game break!

28

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 29/152

Sample Code:http://github.com/stuarthalloway/programming-clojure

29

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 30/152

( defn describe [ snake ]( println "head is " ( first snake))( println "tail is" ( rest snake)))

early impl:a snake

is a sequenceof points rst point is

head

rest is tail

30

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 31/152

( defn describe [[ head & tail ]]( println "head is " head)( println "tail is" tail))

destructurerst elementinto head

captureremainder as a

sequence

destructure remainingelements into tail

31

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 32/152

( defn create-snake [] { :body ( list [ 1 1 ] )

:dir [ 1 0 ] :type :snake :color (Color . 15 160 70) })

snake is more than location

32

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 33/152

( defn describe [ {[ head & tail ] :body }]( println "head is " head)( println "tail is" tail))

2. nested destructureto pull head and tail from the

:body value

1. destructure map,looking up the :tail

33

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 34/152

( defn lose? [ {[ head & tail ] :body }](includes? tail head))

losing the game

34

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 35/152

3. functional

35

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 36/152

data literalstype properties example

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

vector indexed,insert at rear [ 1 2 3 ]

map key/value {:a 100:b 90 }

set key #{ :a :b }

36

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 37/152

higher-orderfunctions

37

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 38/152

lunch-companions

-> ( { :fname "Neal" , :lname "Ford" } { :fname "Stu" , :lname "Halloway" } { :fname "Dan" , :lname "North" })

some data

38

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 39/152

( defn last-name [ x]( get x :last-name )

“getter” functionfn name arg list (vector)

body

39

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 40/152

(sort-byfirst-namelunch-companions)

-> ( { :fname "Dan" , :lname "North" } { :fname "Neal" , :lname "Ford" } {:fname "Stu" , :lname "Halloway" })

pass fn to fncall fn

fn arg

data arg

40

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 41/152

(sort-by( fn [ n]( get n :fname ))

lunch-companions)

anonymous fn

anonymous fn

fn arg

body

41

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 42/152

(sort-by#( get % :fname )lunch-companions)

anonymous #()

anonymous fn

fn arg

42

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 43/152

(sort-by#(% :fname )lunch-companions)

maps are functions

map is fn!

43

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 44/152

(sort-by#( :fname %)lunch-companions)

keywords are functionskeyword

is fn!

44

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 45/152

(sort-by :fname lunch-companions)

beautiful

45

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 46/152

real languages

give a 1-1 ratio of pseudocode/code

46

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 47/152

persistent datastructures

47

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 48/152

persistent data structuresimmutable

“change” by function application

maintain performance guarantees

full-delity old versions

48

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 49/152

persistent example:

linked list

tigerrabbitternnewt

“my” list“your”list

49

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 50/152

bit-partitioned tries

“your”trie

“my”trie

50

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 51/152

log2 n:too slow!

51

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 52/152

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 53/152

clojure: ‘causelog32 n is

fast enough!53

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 54/152

sequencelibrary

54

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 55/152

( first [ 1 2 3 ] )-> 1

( rest [ 1 2 3 ] )-> (2 3)

( cons "hello" [ 1 2 3 ] )-> ( "hello" 1 2 3)

rst / rest / cons

55

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 56/152

( take 2 [ 1 2 3 4 5 ] )-> (1 2)

( drop 2 [ 1 2 3 4 5 ] )-> (3 4 5)

take / drop

56

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 57/152

( range 10)-> (0 1 2 3 4 5 6 7 8 9)

( filter odd? ( range 10))-> (1 3 5 7 9)

( map odd? ( range 10))-> (false true false true false truefalse true false true)

( reduce + ( range 10))-> 45

map / lter / reduce

57

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 58/152

( sort [ 1 56 2 23 45 34 6 43 ] )-> (1 2 6 23 34 43 45 56)

( sort > [ 1 56 2 23 45 34 6 43 ] )-> (56 45 43 34 23 6 2 1)

( sort-by #(.length %)[ "the" "quick" "brown" "fox" ] )-> ( "the" "fox" "quick" "brown" )

sort

58

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 59/152

( conj '(1 2 3) :a )-> ( :a 1 2 3)

( into '(1 2 3) '( :a :b :c ))-> ( :c :b :a 1 2 3)

( conj [ 1 2 3 ] :a )

-> [ 1 2 3 :a ] ( into [ 1 2 3 ] [ :a :b :c ] )-> [ 1 2 3 :a :b :c ]

conj / into

59

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 60/152

( set! *print-length* 5)-> 5

( iterate inc 0)-> (0 1 2 3 4 ...)

( cycle [ 1 2 ] )

-> (1 2 1 2 1 ...)( repeat :d )-> ( :d :d :d :d :d ...)

lazy, innite sequences

60

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 61/152

( interpose \, [ "list" "of" "words" ] )-> ( "list" \, "of" \, "words" )

( apply str ( interpose \, [ "list" "of" "words" ] ))

-> "list,of,words"

( use 'clojure.contrib.str-utils)( str - join \, [ "list" "of" "words" ] ))-> "list,of,words"

interpose

61

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 62/152

( every? odd? [ 1 3 5 ] )-> true

( not-every? even? [ 2 3 4 ] )-> true

( not-any? zero? [ 1 2 3 ] )

-> true( some nil? [ 1 nil 2 ] )-> true

predicates

62

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 63/152

( def jdoe {:name "John Doe" ,:address { :zip 27705, ... }} )

( get-in jdoe [ :address :zip ] )-> 27705

( assoc-in jdoe [ :address :zip ] 27514)-> {:name "John Doe" , :address { :zip 27514 }}

( update-in jdoe [ :address :zip ] inc )-> {:name "John Doe" , :address { :zip 27706 }}

nested ops

63

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 64/152

Ash zna durbatulûk,ash zna gimbatul,ash zna thrakatulûk

agh burzum-ishikrimpatul.

64

h

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 65/152

where are we?1. java interop2. lisp

3. functional

does it work?

65

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 66/152

example:

refactor apachecommonsindexOfAny

66

d f b h

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 67/152

StringUtils .indexOfAny(null, *) = - 1StringUtils .indexOfAny( "" , *) = - 1StringUtils .indexOfAny( *, null) = - 1StringUtils .indexOfAny( *, []) = - 1StringUtils .indexOfAny( "zzabyycdxx" ,[ 'z' , 'a' ]) = 0StringUtils .indexOfAny( "zzabyycdxx" ,[ 'b' , 'y' ]) = 3StringUtils .indexOfAny( "aba" , [ 'z' ]) = - 1

indexOfAny behavior

67

i d Of i l

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 68/152

// From Apache Commons Lang , http: // commons.apache.org / lang /public static int indexOfAny( String str, char[] searchChars){ if (isEmpty(str) || ArrayUtils .isEmpty(searchChars)) { return - 1;

} for (int i = 0; i < str.length(); i ++) {

char ch = str.charAt(i); for (int j = 0; j < searchChars.length; j ++) { if (searchChars[j] == ch) { return i;

}}

} return - 1;}

indexOfAny impl

68

i lif

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 69/152

public static int indexOfAny( String str, char[] searchChars){ when (searchChars)

for (int i = 0; i < str.length(); i ++) {char ch = str.charAt(i); for (int j = 0; j < searchChars.length; j ++) { if (searchChars[j] == ch) { return i;

}}

}}}

simplify corner cases

69

d l

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 70/152

indexOfAny(str, searchChars) { when (searchChars) for (i = 0; i < str.length(); i ++) {

ch = str.charAt(i); for (j = 0; j < searchChars.length; j ++) { if (searchChars[j] == ch) { return i;

}}

}}

}

- type decls

70

h l

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 71/152

indexOfAny(str, searchChars) { when (searchChars) for (i = 0; i < str.length(); i ++) {

ch = str.charAt(i); when searchChars(ch) i;

}}

}

+ when clause

71

h i

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 72/152

indexOfAny(str, searchChars) { when (searchChars) for ([i, ch] in indexed(str)) { when searchChars(ch) i;

}}

}

+ comprehension

72

li if !

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 73/152

( defn index-filter [ pred coll ]( when pred

( for [[ idx elt ] (indexed coll) :when (pred elt) ] idx)))

lispify!

73

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 74/152

functionalis

simpler 74

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 75/152

imperative functional

functions 1 1classes 1 0

internal exit points 2 0

variables 3 0

branches 4 0

boolean ops 1 0

function calls* 6 3

total 18 4

75

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 76/152

functionalis

more general!76

i i d lt

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 77/152

; idxs of heads in stream of coin flips(index-filter # { :h }

[ :t :t :h :t :h :t :t :t :h :h ] )-> (2 4 8 9)

; Fibonaccis pass 1000 at n=17( first

(index-filter #(> % 1000) (fibo)))-> 17

reusing index-lter

77

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 78/152

imperative functional

searches strings searches any sequence

matches characters matches any predicate

returns rst match returns lazy seq of all

matches

78

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 79/152

fp reduces incidentalcomplexity by an

order of magnitude

79

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 80/152

4. concurrency

80

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 81/152

4. stateconcurrency

81

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 82/152

oo is incoherentidentity

???

identity???

?

82

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 83/152

clojureidentity value

identity value

value

explicit semantic

state

83

terms

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 84/152

terms1. value: immutable data in a persistent datastructure

2. identity: series of causally related values

over time3. state: identity at a point in time

84

identity types (references)

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 85/152

identity types (references)

shared isolated

synchronous/coordinated refs/stm -

synchronous/autonomous atoms vars

asynchronous/autonomous agents -

85

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 86/152

identity 1:refs and stm

86

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 87/152

reading value

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 88/152

( deref messages)=> ()

@messages=> ()

reading value

88

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 89/152

updating

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 90/152

( defn add-message [ msg ]( dosync ( alter messages conj msg)))

updatingapply an...

scope atransaction

...update fn

90

unied update model

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 91/152

unied update modelupdate by function applicationreaders require no coordination

readers never block anybody

writers never block readers

91

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 92/152

a sane approachto local state

permits coordination,

but does not require it

92

unied update model

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 93/152

unied update modelref atom agent var

create ref atom agent def

deref deref/@ deref/@ deref/@ deref/@

update alter swap! sendalter-

var-root

93

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 94/152

identity 2:atoms

94

http://blog.bestinclass.dk/index.php/2009/10/brians-functional-brain/

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 95/152

95

board is just a value

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 96/152

( defn new-board "Create a new board with about half the cells set

to :on."( [] ( apply new-board dim-board))( [ dim-x dim-y ]

( for [ x ( range dim-x) ]( for [ y ( range dim-y) ]

( if (< 50 ( rand-int 100)) :on :off ))))))

board is just a value

distinct bodies by arity

96

update is just a function

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 97/152

( defn step "Advance the automation by one step, updating all

cells." [ board ]

(doall( map ( fn [ window ]

( apply #( doall ( apply map rules %&))( doall ( map torus-window window))))

(torus-window board))))

update is just a function

rules

cursor over previous, me, next

97

state is trivial

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 98/152

( let [ stage (atom (new-board))]...)

( defn update-stage "Update the automaton." [ stage ]

(swap ! stage step))

state is trivial

identity initial value

apply a fn update fn

98

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 99/152

send

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 100/152

sendcaller xed thread

pool( send a fn & args)

( apply fn oldval args)

agent

100

state is trivial

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 101/152

( def *logging-agent* ( agent nil))

( if log-immediately?(impl-write ! log-impl level msg err)( send-off *logging-agent*

agent-write ! log level msg err))

state is trivial

identity initial value

apply a fn “update” fn

101

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 102/152

identity 4:vars

102

def forms create vars

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 103/152

( def greeting "hello" )

( defn make-greeting [ n]( str "hello, " n)

def forms create vars

103

vars can be rebound

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 104/152

vars can be rebound

api scope

alter-var-root root binding

set! thread-local, permanent

binding thread-local, dynamic

104

system settings

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 105/152

( set! *print-length* 20)=> 20

primes

=> (2 3 5 7 11 13 17 19 23 29 31 37 4143 47 53 59 61 67 71 ...)

( set! *print-length* 5)=> 5

primes=>(2 3 5 7 11 ...)

system settings

105

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 106/152

var usage

*in*, *out*, *err* standard streams

*print-length*,*print-depth* structure printing

*warn-on-reflection* performance tuning

*ns* current namespace

*file* le being evaluated

*command-line-args* guess

106

with- helper macros

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 107/152

( def bar 10)-> #'user/bar

( with-ns 'foo ( def bar 20))-> #'foo/bar

user/bar-> 10

foo/bar-> 20

with ... helper macros

bind a varfor a dynamic

scope

107

other def forms

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 108/152

form usagedefonce set root binding once

defvar var plus docstring

defunbound no initial binding

defstruct map with slots

defalias same metadata as original

defhinted infer type from initial binding

defmemo defn + memoize

other def forms

many of these are in clojure.contrib.def...108

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 109/152

identity:more options

109

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 110/152

use commutewhen updatecan happen

anytime110

not safe for commute

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 111/152

( defn next-id "Get the next available id."

[](dosync

( alter ids inc )))

not safe for commute

111

safe!

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 112/152

( defn increment-counter "Bump the internal count." []

(dosync( alter ids inc ))

nil)

safe!

112

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 113/152

prefer send-off

if agent ops

might block 113

send

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 114/152

sendcaller xed thread

pool( send a fn & args)

( apply fn oldval args)

agent

114

send off

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 115/152

send-off caller agent

cached thread pool

( apply fn oldval args)

( send a fn & args)

115

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 116/152

use ref-set to setinitial/base state

116

unied update, revisited

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 117/152

unied update, revisitedupdatemechanism ref atom agent

pure functionapplication alter swap! send

pure function(commutative) commute - -

pure function(blocking) - - send-off

setter ref-set reset! -

117

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 118/152

send-off to *agent*

for backgrounditeration

118

monte carlo via

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 119/152

( defn background-pi [ iter- count ]( let

[ agt ( agent { :in-circle 0 :total 0})continue (atom true)iter ( fn sim [ a- val ]

( when continue ( send-off *agent* sim))(run-simulation a- val iter- count )) ]

( send-off agt iter) { :guesser agt :continue atom })

o te ca o v a

ongoing agent

do thework

queue morework

escape hatch

119

(not= agents actors)

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 120/152

( g )

agents actors

in-process only oop

no copying copying

no deadlock can deadlock

no coordination can coordinate

120

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 121/152

validation

121

create afunction that checks

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 122/152

( def validate-message-list( partial

every? #( and ( :sender %) ( :text %))))

( def messages( ref

()

:validator validate-message-list))

every item...

for some criteria

and associate fn with updates to a ref

122

agent error handling

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 123/152

( def counter ( agent 0 :validator integer? ))-> #'user/counter

( send counter ( constantly :fail ))-> #<Agent 0>

( agent-errors counter)-> (#<IllegalStateException

java.lang.IllegalStateException:Invalid reference state>)

( clear-agent-errors counter)-> nil

@counter-> 0

g g

will fail soon

list of errors

reset and move on

123

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 124/152

agents

andtransactions

124

tying agent to a tx

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 125/152

( defn add-message-with-backup [ msg ]

( dosync ( let [ snapshot ( alter messages conj msg) ]( send-off backup-agent ( fn [ filename ]

(spit filename snapshot)filename))

snapshot)))

y g g

exactly once if tx succeeds

125

where are we?

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 126/152

1. java interop2. lisp

3. functional

4. value/identity/state

does it work?

126

a workable approach to state

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 127/152

good values: persistent data structuresgood identities: references

mostly functional?

usable by mortals?

127

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 128/152

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 129/152

1 line in 1000

creates areference

129

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 130/152

project loc calls to

ref

calls to

agent

calls to

atom

clojure 7232 3 1 2

clojure-contrib 17032 22 2 12

compojure 1966 1 0 0

incanter 6248 1 0 0

130

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 131/152

usable bymortals?

131

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 132/152

; compojure session management( def memory-sessions ( ref {} ))

( defmethod read-session :memory [ repository id ]

(@memory-sessions id))

( defmethod write-session :memory [ repository session ]

(dosync( alter memory-sessions

assoc (session :id ) session)))

multimethoddispatch

read update

132

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 133/152

; from clojure core( defn memoize [ f ]

( let [ mem (atom {} ) ]( fn [ & args ]

( if-let [ e ( find @mem args) ]( val e)( let [ ret ( apply f args) ]

(swap ! mem assoc args ret)ret)))))

cache previousresults

cache hit

cache miss:call f, add to

cache

133

clojure

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 134/152

values areimmutable, persistent

identities are

well-specied, consistent

state ismostly functional

usable by mortals

134

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 135/152

languages thatemphasizeimmutability are

better at mutation135

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 136/152

timemanagement

136

prepare to parallelize

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 137/152

( defn step "Advance the automation by one step, updating all

cells."

[ board ](doall

( map ( fn [ window ]( apply #( doall ( apply map rules %&))

( doall ( map torus-window window))))(torus-window board))))

137

done

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 138/152

( defn step "Advance the automation by one step, updating all

cells."

[ board ](doall

( p map ( fn [ window ]( apply #( doall ( apply map rules %&))

( doall ( map torus-window window))))(torus-window board))))

138

delay

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 139/152

( def e ( delay (expensive-calculation)))

-> #'demo.delay/e

( delay? e)-> true

( force e)-> :some-result

( deref e)

-> :some-result

@e-> :some-result

rst call blocksuntil work

completes onthis thread,later calls hit

cache

139

future

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 140/152

( def e1 (future (expensive-calculation)))-> #'demo.future/e1

( deref e1)-> :some-result

@e1-> :some-result

rst call blocksuntil work completes on

other thread,later calls hit

cache

140

cancelling a future

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 141/152

( def e2 (future (expensive-calculation)))-> #'demo.future/e2

(future-cancel e2)-> true

(future-cancelled? e2)-> true

( deref e2)-> java.util.concurrent.CancellationException

141

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 142/152

transients

142

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 143/152

build structureon one thread,then release into

the wild143

persistent...

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 144/152

( defn vrange [ n ]( loop [ i 0 v []]

( if (< i n)( recur ( inc i) ( conj v i))v)))

144

...to transient

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 145/152

( defn vrang2 [ n ]( loop [ i 0 v ( transient [])]

( if (< i n)( recur ( inc i) ( conj! v i))( persistent v))))

enter transient world

use transient updaterreturn topersistent world

145

fast!

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 146/152

( time ( def v (vrange 1000000)))"Elapsed time: 1130.721 msecs"

( time ( def v2 (vrange2 1000000)))"Elapsed time: 82.191 msecs"

146

transients

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 147/152

usage:transient

bang updates: assoc! conj! etc.

persistent!optimization, not coordination

O(1) creation from persistent object

fast, isolated updates

O(1) conversion back to persistent object

147

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 148/152

oo: one identity ts all

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 149/152

y

state

behavior

constructors

encapsulationthread-safety

functions

validation

dispatch

identity

149

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 150/152

clojure: bespoke

code in an off-the-rack world

150

clojure’s four elevators

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 151/152

java interoplisp

functional

state

151

Email: stu@thinkrelevance.com Office: 919-442-3030Twitter: twitter.com/stuarthallowayFacebook: stuart.hallowayGi h b h ll

8/14/2019 Http://Github.com/Stuarthalloway/Clojure Presentations

http://slidepdf.com/reader/full/httpgithubcomstuarthallowayclojure-presentations 152/152

Github: stuarthallowayThis talk: http://github.com/stuarthalloway/clojure-presentationsTalks: http://blog.thinkrelevance.com/talksBlog: http://blog.thinkrelevance.com Book: http://tinyurl.com/clojure