clojure: towards the essence of programming (what's next? conference, may 2011)

84
© 2011 Howard M. Lewis Ship Clojure: Towards The Essence Of Programming Howard M. Lewis Ship

Upload: howard-lewis-ship

Post on 17-Jan-2015

10.539 views

Category:

Technology


2 download

DESCRIPTION

As presented at What's Next? Conference, 26 May 2011, in Paris. http://www.whatsnextparis.com/

TRANSCRIPT

Page 1: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

Clojure: Towards The Essence Of ProgrammingHoward M. Lewis Ship

Page 2: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

essence |ˈesəns|nounthe intrinsic nature or indispensable quality of something, esp. something abstract, that determines its character : conflict is the essence of drama.

Page 3: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

Operating System

Language

Libraries

Frameworks

Applications

Page 4: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship© 2011 Howard M. Lewis Ship

Your code

Page 5: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

Ceremony Vs. Essence

Page 6: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

Is your language ...

Page 7: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship… holding you back?

Page 8: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

Stockticker: AAPL

lastTrade: 203.25open: 204.50shares: 100

Stockticker: MSFT

lastTrade: 29.12open: 29.08shares: 50

Stockticker: ORCL

lastTrade: 21.90open: 21.83shares: 200

public static void sortByLastTrade(List<Stock> portfolio) { Comparator<Stock> c = new Comparator<Stock>() { public int compare(Stock o1, Stock o2) { return o1.getLastTrade() - o2.getLastTrade(); } };

Collections.sort(portfolio, c);}

public static void sortByOpen(List<Stock> portfolio) { Comparator<Stock> c = new Comparator<Stock>() { public int compare(Stock o1, Stock o2) { return o1.getOpen() - o2.getOpen(); } };

Collections.sort(portfolio, c);}

Page 9: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

{ }:ticker AAPL

:last-trade 203.25

:open 204.50 { }:ticker MSFT

:last-trade 29.12

:open 29.08 { }:ticker ORCL

:last-trade 21.90

:open 21.83

:shares 100 :shares 50 :shares 200

user=> portfolio[{:ticker "AAPL", :last-trade 203.25M, :open 204.50M, :shares 100} {:ticker "MSFT", :last-trade 29.12M, :open 29.08M, :shares 50} {:ticker "ORCL", :last-trade 21.90M, :open 21.83M, :shares 200}]user=> (sort-by :last-trade portfolio)({:ticker "ORCL", :last-trade 21.90M, :open 21.83M, :shares 200} {:ticker "MSFT", :last-trade 29.12M, :open 29.08M, :shares 50} {:ticker "AAPL", :last-trade 203.25M, :open 204.50M, :shares 100})user=> (sort-by :shares portfolio)({:ticker "MSFT", :last-trade 29.12M, :open 29.08M, :shares 50} {:ticker "AAPL", :last-trade 203.25M, :open 204.50M, :shares 100} {:ticker "ORCL", :last-trade 21.90M, :open 21.83M, :shares 200})user=> (defn value-at-open [stock] …)#'user/value-at-openuser=> (sort-by value-at-open portfolio)({:ticker "MSFT", :last-trade 29.12M, :open 29.08M, :shares 50} {:ticker "ORCL", :last-trade 21.90M, :open 21.83M, :shares 200} {:ticker "AAPL", :last-trade 203.25M, :open 204.50M, :shares 100})

Page 10: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

Clojure: The Language

Page 11: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

(defn render-json "Renders JSON content (typically, a map or a seq) as the response. The response content type is set to \"application/json\". Returns true." [env json-value] (let [response (-> env :servlet-api :response)] (.setContentType response "application/json") (with-open [writer (.getWriter response)] (binding [*out* writer] (print-json json-value)))) true)

Aargh!

Page 12: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

(defn render-json "Renders JSON content (typically, a map or a seq) as the response. The response content type is set to \"application/json\". Returns true." [env json-value] (let [response (-> env :servlet-api :response)] (.setContentType response "application/json") (with-open [writer (.getWriter response)] (binding [*out* writer] (print-json json-value)))) true)

Panic Ensues

Ouch!

Page 13: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

Page 14: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

defn render-json env json-value

letresponse -> env :servlet-api :response

.setContentType response "application/json"

with-open writer .getWriter response

binding *out* writer

print-json json-value

Page 15: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

public static boolean renderJSON(Environment env, JSONObject object) { HttpServletResponse response = env.getServletAPI().getResponse(); response.setContentType("application/json"); Writer writer = null; try { writer = response.getWriter(); printJSON(writer, object); } finally { if (writer != null) { writer.close(); } } return true;}

Page 16: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

public static boolean renderJSON(Environment env, JSONObject object) { HttpServletResponse response = env.getServletAPI().getResponse(); response.setContentType("application/json"); Writer writer = null; try { writer = response.getWriter(); printJSON(writer, object); } finally { if (writer != null) { writer.close(); } } return true;}

(defn render-json "Renders JSON content (typically, a map or a seq) as the response. The response content type is set to \"application/json\". Returns true." [env json-value] (let [response (-> env :servlet-api :response)] (.setContentType response "application/json") (with-open [writer (.getWriter response)] (binding [*out* writer] (print-json json-value)))) true)

24/234

24/375

Page 17: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

public static float toFahrenheit(float celcius) { return 9 * celcius / 5 + 32;}

High Precedence

Low Precedence

*

9 celcius

/

+

5

32

(+ (/ (* 9 c) 5) 32)

Page 18: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

public static toFahrenheit(F)F L0 LINENUMBER 5 L0 LDC 9.0 FLOAD 0 FMUL LDC 5.0 FDIV LDC 32.0 FADD FRETURN L1 LOCALVARIABLE celcius F L0 L1 0 MAXSTACK = 2 MAXLOCALS = 1

public static float toFahrenheit(float celcius) { return 9 * celcius / 5 + 32;}

$ hexdump bin/org/example/Conversions.class 0000000 ca fe ba be 00 00 00 31 00 17 07 00 02 01 00 170000010 6f 72 67 2f 65 78 61 6d 70 6c 65 2f 43 6f 6e 760000020 65 72 73 69 6f 6e 73 07 00 04 01 00 10 6a 61 760000030 61 2f 6c 61 6e 67 2f 4f 62 6a 65 63 74 01 00 060000040 3c 69 6e 69 74 3e 01 00 03 28 29 56 01 00 04 430000050 6f 64 65 0a 00 03 00 09 0c 00 05 00 06 01 00 0f0000060 4c 69 6e 65 4e 75 6d 62 65 72 54 61 62 6c 65 010000070 00 12 4c 6f 63 61 6c 56 61 72 69 61 62 6c 65 540000080 61 62 6c 65 01 00 04 74 68 69 73 01 00 19 4c 6f0000090 72 67 2f 65 78 61 6d 70 6c 65 2f 43 6f 6e 76 6500000a0 72 73 69 6f 6e 73 3b 01 00 0c 74 6f 46 61 68 7200000b0 65 6e 68 65 69 74 01 00 04 28 46 29 46 04 41 1000000c0 00 00 04 40 a0 00 00 04 42 00 00 00 01 00 07 6300000d0 65 6c 63 69 75 73 01 00 01 46 01 00 0a 53 6f 7500000e0 72 63 65 46 69 6c 65 01 00 10 43 6f 6e 76 65 7200000f0 73 69 6f 6e 73 2e 6a 61 76 61 00 21 00 01 00 030000100 00 00 00 00 00 02 00 01 00 05 00 06 00 01 00 070000110 00 00 00 2f 00 01 00 01 00 00 00 05 2a b7 00 080000120 b1 00 00 00 02 00 0a 00 00 00 06 00 01 00 00 000000130 03 00 0b 00 00 00 0c 00 01 00 00 00 05 00 0c 000000140 0d 00 00 00 09 00 0e 00 0f 00 01 00 07 00 00 000000150 35 00 02 00 01 00 00 00 0b 12 10 22 6a 12 11 6e0000160 12 12 62 ae 00 00 00 02 00 0a 00 00 00 06 00 010000170 00 00 00 05 00 0b 00 00 00 0c 00 01 00 00 00 0b0000180 00 13 00 14 00 00 00 01 00 15 00 00 00 02 00 160000190

Page 19: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

Clojure: Form Is

Structure

Page 20: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

(defn to-fahrenheit [celcius] (+ (/ (* 9 celcius) 5) 32))

Page 21: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

(defn biggest "Find the maximum of two numbers" [x y] (if (> x y) x y))

(biggest 5 42)

'(1 2 "three") List of values

Function call

Function definition

Page 22: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

Read Eval Print Loopuser=> (defn biggest "Find the maximum of two numbers" [x y] (if (> x y) x y))#=(var user/biggest)user=> (biggest 5 42)42user=> (doc biggest)-------------------------user/biggest([x y]) Find the maximum of two numbersniluser=> '(1 2 3)(1 2 3)user=> '(biggest 5 42)(biggest 5 42)user=> (first '(biggest 5 42))biggestuser=> (eval '(biggest 5 42))42

Page 23: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship23

Operating System

JVM

Java Libraries

User Classes

ClojureRepl Input

Clojure Source Files

Java Compiler

Source Code

Evaluator

Page 24: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

Simple Literals• Strings

• Characters

• nil

• true

• false

• integers

• floating point numbers

• ratios

user=> "A Clojure String""A Clojure String"user=> \space\spaceuser=> \A\Auser=> nilniluser=> truetrueuser=> falsefalseuser=> 00user=> 2.52.5user=> 22/722/7

nil is Java null

Page 25: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

Keywords•Literal values

•Singleton instances

•Especially useful as map keys

user=> (identical? :a-keyword :a-keyword)trueuser=> (str "a" "-" "string")"a-string"user=> (identical? "a-string" (str "a" "-" "string"))falseuser=> (keyword "a-keyword"):a-keyworduser=> (identical? :a-keyword (keyword "a-keyword"))true

Page 26: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

Lists

2

3

lst

1user=> (def lst '(1 2 3))#=(var user/lst)user=> lst(1 2 3)user=> (first lst)1user=> (rest lst)(2 3)

Page 27: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

Lists

2

3

lst

1user=> (conj lst 4)(4 1 2 3)user=> (cons 4 lst)(4 1 2 3)

4

conjoin: Add element to list

construct: new seq with new first element

Page 28: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

Vectors

user=> (def v [:moe :larry :curly])#=(var user/v)user=> v[:moe :larry :curly]user=> (first v):moeuser=> (rest v)(:larry :curly)user=> (conj v :shemp)[:moe :larry :curly :shemp]user=> (cons :shemp v)(:shemp :moe :larry :curly)user=> v[:moe :larry :curly]

first, rest and others work on lists, vectors or

any seq

Page 29: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

Maps

user=> (def m {:first-name "Howard" :last-name "Lewis Ship"})#=(var user/m)user=> m{:last-name "Lewis Ship", :first-name "Howard"}user=> (get m :last-name)"Lewis Ship"user=> (:first-name m)"Howard"user=> (assoc m :company "TWD"){:company "TWD", :last-name "Lewis Ship", :first-name "Howard"}user=> m{:last-name "Lewis Ship", :first-name "Howard"}user=> (get m:ssn)nil

Keywords act as a function that takes a map

Page 30: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

Sets

user=> (def s #{"Howard" "Suzanne" "Molly" "Jim"})#=(var user/s)user=> s#{"Howard" "Jim" "Molly" "Suzanne"}user=> (contains? s "Howard")trueuser=> (contains? s "howard")falseuser=> (conj s "Howard")#{"Howard" "Jim" "Molly" "Suzanne"}user=> (conj s "Scott")#{"Howard" "Jim" "Molly" "Suzanne" "Scott"}

Page 31: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

Functional Programming

Page 32: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

My First Program

10 X = 120 PRINT X30 X = X + 140 GOTO 20

"No it doesn't"-- Miss Dimascio

Page 33: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

Immutability

Page 34: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

function |ˈfə ng k sh ən|

nounA function, in a mathematical sense, expresses the idea that one quantity (the argument of the function, also known as the input) completely determines another quantity (the value, or the output).

Page 35: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

Predictable

Page 36: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

Isolation From Time

Page 37: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

user=> (def names ["fred" "barney" ".hidden" "wilma"])#=(var user/names)user=> (filter #(not (.startsWith % ".")) names)("fred" "barney" "wilma")user=> (remove #(.startsWith % ".") names)("fred" "barney" "wilma")

(filter #(not (.startsWith % ".")) names)

#(…) anonymous function

% anonymous parameter

(filter (fn [name] (not (.startsWith name "."))) names)

Inline anoymous function Java Interop

Page 38: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

(defn require-extension [ext] (fn [file-name] (= ext (last (split-string file-name ".")))))

(filter #(not (.startsWith % ".")) names)

(filter (require-extension "gz") names)

Function as parameter

Function as return value

❝Closure Oriented

Programming❞Composing functions

Page 39: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

Java: Imperative Steps

Page 40: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

Stockticker: AAPL

lastTrade: 203.25open: 204.50shares: 100

Stockticker: MSFT

lastTrade: 29.12open: 29.08shares: 50

Stockticker: ORCL

lastTrade: 21.90open: 21.83shares: 200

public static List<Double> getOpens(List<Stock> portfolio) { List<Double> result = new ArrayList<Double>();

for (Stock stock : portfolio) { result.add(stock.getOpen()); }

return result;}

Page 41: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

Clojure: Flow of Transformations

Page 42: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

{ }:ticker AAPL

:last-trade 203.25

:open 204.50 { }:ticker MSFT

:last-trade 29.12

:open 29.08 { }:ticker ORCL

:last-trade 21.90

:open 21.83

:shares 100 :shares 50 :shares 200

user=> portfolio[{:ticker "AAPL", :last-trade 203.25M, :open 204.50M, :shares 100} {:ticker "MSFT", :last-trade 29.12M, :open 29.08M, :shares 50} {:ticker "ORCL", :last-trade 21.90M, :open 21.83M, :shares 200}]user=> (map #(get % :open) portfolio)(204.50M 29.08M 21.83M)user=> (map :open portfolio)(204.50M 29.08M 21.83M)

Page 43: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

Laziness Is a Virtue

Page 44: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

user=> (take 20 (iterate inc 1))(1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20)user=> (take 20 (map * (iterate inc 1) (iterate inc 1)))(1 4 9 16 25 36 49 64 81 100 121 144 169 196 225 256 289 324 361 400)

Page 45: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

Page 46: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

Lazyf

user=> (defn last-trade-value [stock] (* (:last-trade stock) (:shares stock)))#'user/last-trade-valueuser=> (map last-trade-value portfolio)(20325.00M 1456.00M 4380.00M)user=> (map #(assoc % :last-trade-value (last-trade-value %)) portfolio)({:last-trade-value 20325.00M, :ticker "AAPL", :last-trade 203.25M, :open 204.50M, :shares 100} {:last-trade-value 1456.00M, :ticker "MSFT", :last-trade 29.12M, :open 29.08M, :shares 50} {:last-trade-value 4380.00M, :ticker "ORCL", :last-trade 21.90M, :open 21.83M, :shares 200})

Page 47: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

f

user=> (map last-trade-value portfolio)(20325.00M 1456.00M 4380.00M)user=> (reduce + (map last-trade-value portfolio))26161.00Muser=> (reduce + 0 [])0user=> (reduce + nil)0 Initial

Value

Page 48: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

user=> (def input-string "Clojure is a fascinating language with unique capabilities and total integration with Java.")#'user/input-stringuser=> (seq input-string) (\C \l \o \j \u \r \e \space \i \s \space \a \space \f \a \s \c \i \n \a \t \i \n \g \space \l \a \n \g \u \a \g \e \space \w \i \t \h \space \u \n \i \q \u \e \space \c \a \p \a \b \i \l \i \t \i \e \s \space \a \n \d \space \t \o \t \a \l \space \i \n \t \e \g \r \a \t \i \o \n \space \w \i \t \h \space \J \a \v \a \.)user=> (reduce (fn [m k] (update-in m [k] #(inc (or % 0)))) {} (seq input-string)) {\space 12, \a 12, \b 1, \C 1, \c 2, \d 1, \e 5, \f 1, \g 4, \h 2, \i 11, \J 1, \j 1, \l 4, \. 1, \n 7, \o 3, \p 1, \q 1, \r 2, \s 3, \t 8, \u 4, \v 1, \w 2}

f

Page 49: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

Lazy

user=> (range 0 4)(0 1 2 3)user=> (for [suit [:hearts :clubs :spades :diamonds] value (range 1 4)] [suit value])([:hearts 1] [:hearts 2] [:hearts 3] [:clubs 1] [:clubs 2] [:clubs 3] [:spades 1] [:spades 2] [:spades 3] [:diamonds 1] [:diamonds 2] [:diamonds 3])user=> (for [x (range 0 4) y (range 0 (inc x))] [x y])([0 0] [1 0] [1 1] [2 0] [2 1] [2 2] [3 0] [3 1] [3 2] [3 3])user=> (for [x (range 0 9) :when (odd? x) y (range 1 (inc x))] [x y])([1 1] [3 1] [3 2] [3 3] [5 1] [5 2] [5 3] [5 4] [5 5] [7 1] [7 2] [7 3] [7 4] [7 5] [7 6] [7 7])

List Comprehension

Page 50: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis ShipPaul Graham

❝Somehow the idea of reusability got attached to

object-oriented programming in the 1980s, and no amount of evidence to the contrary seems to be

able to shake it free.❞

Page 51: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

Language Ownership

Page 52: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

Who Owns The Java Language?

Mark ReinholdBrian Goetz

Page 53: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

Not You

Page 54: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

Operating System

JVM

Java Libraries

User Classes

ClojureRepl Input

Clojure Source Files

Java Compiler

Source Code

Evaluator

Page 55: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

Who Owns Clojure?

Page 56: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

Clojure In Clojure

Page 57: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

if (person.isPharaoh() && person.isDead() && buildPyramid(person)) { person.entomb();}

boolean isPharoah = person.isPharoah();boolean isDead = person.isDead();boolean pyramidComplete = buildPyramid(person);

if (isPharoah && isDead && pyramidComplete) { person.entomb();}

Short Circuiting Evaluation

Everyone gets a Pyramid!

Dead Pharoahs get a Pyramid

Page 58: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

(if (all-true (.isPharaoh person) (.isDead person) (build-pyramid person)) (.entomb person))

public static boolean allTrue(boolean... inputs) { for (boolean input : inputs) { if (!input) return false; }

return true;}

Function invocation: evaluate all parameters

first

Java version of all-true

(defn all-true ([] true) ([x] x) ([x & more] (if x (apply all-true more) x)))

Page 59: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

(if (and (.isPharaoh person) (.isDead person) (build-pyramid person)) (.entomb person))

and short-circuits, so it's not a function

And what exactly is if ?

user=> (doc and)-------------------------clojure.core/and([] [x] [x & next])Macro Evaluates exprs one at a time, from left to right. If a form returns logical false (nil or false), and returns that value and doesn't evaluate any of the other expressions, otherwise it returns the value of the last expr. (and) returns true.nil

Page 60: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

Caution: Head Exploding Zone

Page 61: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

Literals

"Hello" 2.5 nil

Vectors

[ … ]

Lists

'(1 2 3)

Maps

{ … }Function

Calls,Special Forms,Macros(a b c)

Sets

#{ … }

Forms

Page 62: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

(if test then else?)

Evaluates test. If not the singular values nil or false, evaluates and yields then, otherwise, evaluates and yields else. If else is not supplied it defaults to nil. …

If: Special Formuser=> (doc if)-------------------------ifSpecial Form Please see http://clojure.org/special_forms#ifnil

Page 63: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

Clojure Macros

Reader

Evaluator

Bytecode Generation

Macro Expansion

Page 64: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

(if (and (.isPharaoh person) (.isDead person) (build-pyramid person)) (.entomb person))

(if (if (.isPharaoh person) (if (.isDead person) (if (build-pyramid person) (.entomb person)))))

Macro Expansion

Approximate expansion of macro

Page 65: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

(defmacro and  ([] true)  ([x] x)  ([x & next]   `(let [and# ~x]      (if and# (and ~@next) and#))))

(if (and (.isPharaoh person) (.isDead person) (build-pyramid person)) (.entomb person))

(if (let [and_4422_auto (.isPharaoh person)] (if and_4422_auto (and (.isDead person) (build-pyramid person)) and_4422_auto)) (.entomb person))

Evaluate (.isPharaoh person)

only once

Macro Expansion

Page 66: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

Bytecode Generation

Code Forms

Macro Expansion

def if let fn ….

Page 67: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

Boilerplate

(deftest test-link (with-mocks [request HttpServletRequest response HttpServletResponse] (:train (expect .getContextPath request "/ctx") (expect .encodeURL response "/ctx/accounts/list" "*encoded*")) (:test (is (= (link request response list-accounts-with-loop) "*encoded*")))))

public void testLink() { IMocksControl control = EasyMock.createControl(); HttpServletRequest request = control.newMock(HttpServletRequest.class); HttpServletResponse response = control.newMock(HttpServletResponse.class); EasyMock.expect(request.getContextPath()).andReturn("/ctx"); EasyMock.expect(response.encodeURL("/ctx/accounts/list")).andReturn("*encoded*"); control.replay();

assertEquals(…, "*encoded*");

control.verify();}

Page 68: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

Domain Specific Languages(defview root-index [env] :html [ :head [ :title [ "Cascade Blog" ] ] :body [ :h1 [ "Cascade Blog" ]

:ul { :class "recent-postings" } [ (template-for [posting (recent-postings env)]

:li [ (render-link env show-posting (posting :id) (posting :title)) ])

] ] ])

:head

:html

:title

"Cascade Blog"

:h1

"Cascade Blog"

:ul

(template-for …)

:body

Page 69: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

(defn list-items [coll] (template (format "%d items" (count coll)) :ul {:class :item-list} [ (template-for [item coll] :li [item])))

(defn list-items [coll] (cascade.internal.viewbuilder/combine (format "%d items" (count coll)) (cascade.dom/element-node :ul {:class :item-list} (cascade.internal.viewbuilder/combine (for [item coll] (cascade.dom/element-node :li nil (cascade.internal.viewbuilder/combine item)))))))

Expand simple

placeholder to executable code

Extend Clojure

language from w

ithin C

lojure

Page 70: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

Wrap Up

Page 71: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

essence |ˈesəns|nounthe intrinsic nature or indispensable quality of something, esp. something abstract, that determines its character : conflict is the essence of drama.

Page 72: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis ShipBrian Kernigan

❝Controlling complexity is the essence of computer

programming❞

Page 73: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

Control is the Essence of

Programming

Page 74: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

Evaluation

Page 75: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

Language or Language Toolkit?

Page 76: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

Page 77: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

Clojure•1.2 release: 19 Aug 2010

•Simple, regular syntax

• Improves on Lisp: vectors, maps, sets

•Fully integrates with Java

• Impressive functional & concurrency support

•Most features not covered here

http://www.clojure.org

Page 78: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

Page 79: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

http://java.ociweb.com/mark/clojure/article.html

Page 80: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

http://tapestryjava.blogspot.com

Page 81: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship© 2011 Howard M. Lewis Ship

Page 82: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship© 2011 Howard M. Lewis Ship

Page 83: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

Image Credits© 2007 John Kannenberghttp://www.flickr.com/photos/jkannenberg/541057337/

© 2008 Alexandre Pizzerahttp://www.flickr.com/photos/alecss/2563917055

© 2008 Marcin Wicharyhttp://www.flickr.com/photos/mwichary/2827326852/

© 2008 Jonathan Ziapourhttp://www.flickr.com/photos/jonathanziapour/2613204502/

© Randall Munroehttp://xkcd.com/297/

© 2010 yuichi.sakurabahttp://www.flickr.com/photos/skrb/5107280055

© 2007 Jon Fifehttp://flickr.com/photos/good-karma/577632972/

© 2008 Howard M. Lewis Shiphttp://www.flickr.com/photos/hlship/3108306576

© 2006 scott ogilviehttp://www.flickr.com/photos/scottog/100582274/

© 2008 Ariel H.http://www.flickr.com/photos/fotosrotas/2730733412/

© 2008 Manu Gómezhttp://www.flickr.com/photos/manugomi/2884678938/

Page 84: Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)

© 2011 Howard M. Lewis Ship

Image Credits© 2009 Howard M. Lewis Shiphttp://www.flickr.com/photos/hlship/3603090614/

© 2003 A. Lipsonhttp://www.andrewlipson.com/escher/relativity.html

© 2006 John Ryan Brubakerhttp://www.flickr.com/photos/subconscience/297682093/

© 2007 Alan Chiahttp://flickr.com/photos/seven13avenue/2080281038/

© 2003 Randall Munroehttp://xkcd.com/224/