SlideShare a Scribd company logo
1 of 84
Download to read offline
Clojure: Towards
The Essence Of
Programming
Howard M. Lewis Ship

                       © 2011 Howard M. Lewis Ship
essence
noun
the intrinsic nature or indispensable quality of
something, esp. something abstract, that
determines its character : conflict is the essence of
drama.



                                           © 2011 Howard M. Lewis Ship
Applications

  Frameworks

    Libraries

   Language

Operating System


                   © 2011 Howard M. Lewis Ship
Your code




            © 2011 Howard M. Lewis Ship
Ceremony
Vs. Essence
        © 2011 Howard M. Lewis Ship
Is your language ...




                       © 2011 Howard M. Lewis Ship
… holding you back?
            © 2011 Howard M. Lewis Ship
Stock                 Stock               Stock
                  ticker: AAPL          ticker: MSFT       ticker: ORCL
               lastTrade: 203.25      lastTrade: 29.12   lastTrade: 21.90
                 open: 204.50            open: 29.08        open: 21.83
                   shares: 100            shares: 50         shares: 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);
                 }



                                                                   © 2011 Howard M. Lewis Ship
:ticker     AAPL             :ticker     MSFT           :ticker     ORCL


    :last-trade   203.25         :last-trade   29.12        :last-trade   21.90

{     :open       204.50   } {     :open       29.08   }{     :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-open
    user=> (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})




                                                                   © 2011 Howard M. Lewis Ship
Clojure: The
Language
               © 2011 Howard M. Lewis Ship
Aargh!
(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)




                                                             © 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)]                   Panic Ensues
    (.setContentType response "application/json")
    (with-open [writer (.getWriter response)]
      (binding [*out* writer]
        (print-json json-value))))
  true)

                                   Ouch!




                                                             © 2011 Howard M. Lewis Ship
© 2011 Howard M. Lewis Ship
defn render-json 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




                                                   © 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;
}




                                                          © 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))))                        24/234
      true)

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;                                                      24/375
}

                                                           © 2011 Howard M. Lewis Ship
public static float toFahrenheit(float celcius) {
            return 9 * celcius / 5 + 32;
          }


                          High           Low
                       Precedence     Precedence




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

9       celcius




                                                        © 2011 Howard M. Lewis Ship
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   17
  public static toFahrenheit(F)F      0000010 6f 72 67 2f 65 78 61 6d 70 6c 65 2f   43   6f   6e   76
   L0                                 0000020 65 72 73 69 6f 6e 73 07 00 04 01 00
                                      0000030 61 2f 6c 61 6e 67 2f 4f 62 6a 65 63
                                                                                    10
                                                                                    74
                                                                                         6a
                                                                                         01
                                                                                              61
                                                                                              00
                                                                                                   76
                                                                                                   06
    LINENUMBER 5 L0                   0000040 3c 69 6e 69 74 3e 01 00 03 28 29 56   01   00   04   43
                                      0000050 6f 64 65 0a 00 03 00 09 0c 00 05 00   06   01   00   0f
    LDC 9.0                           0000060 4c 69 6e 65 4e 75 6d 62 65 72 54 61   62   6c   65   01
                                      0000070 00 12 4c 6f 63 61 6c 56 61 72 69 61   62   6c   65   54
    FLOAD 0                           0000080 61 62 6c 65 01 00 04 74 68 69 73 01   00   19   4c   6f
    FMUL                              0000090 72 67 2f 65 78 61 6d 70 6c 65 2f 43   6f   6e   76   65
                                      00000a0 72 73 69 6f 6e 73 3b 01 00 0c 74 6f   46   61   68   72
    LDC 5.0                           00000b0 65 6e 68 65 69 74 01 00 04 28 46 29   46   04   41   10
                                      00000c0 00 00 04 40 a0 00 00 04 42 00 00 00   01   00   07   63
    FDIV                              00000d0 65 6c 63 69 75 73 01 00 01 46 01 00   0a   53   6f   75
    LDC 32.0                          00000e0 72 63 65 46 69 6c 65 01 00 10 43 6f
                                      00000f0 73 69 6f 6e 73 2e 6a 61 76 61 00 21
                                                                                    6e
                                                                                    00
                                                                                         76
                                                                                         01
                                                                                              65
                                                                                              00
                                                                                                   72
                                                                                                   03
    FADD                              0000100 00 00 00 00 00 02 00 01 00 05 00 06   00   01   00   07
                                      0000110 00 00 00 2f 00 01 00 01 00 00 00 05   2a   b7   00   08
    FRETURN                           0000120 b1 00 00 00 02 00 0a 00 00 00 06 00   01   00   00   00
                                      0000130 03 00 0b 00 00 00 0c 00 01 00 00 00   05   00   0c   00
   L1                                 0000140 0d 00 00 00 09 00 0e 00 0f 00 01 00   07   00   00   00
    LOCALVARIABLE celcius F L0 L1 0   0000150 35 00 02 00 01 00 00 00 0b 12 10 22   6a   12   11   6e
                                      0000160 12 12 62 ae 00 00 00 02 00 0a 00 00   00   06   00   01
    MAXSTACK = 2                      0000170 00 00 00 05 00 0b 00 00 00 0c 00 01   00   00   00   0b
                                      0000180 00 13 00 14 00 00 00 01 00 15 00 00   00   02   00   16
    MAXLOCALS = 1                     0000190




                                                                            © 2011 Howard M. Lewis Ship
Clojure:
 Form Is
Structure
       © 2011 Howard M. Lewis Ship
(defn to-fahrenheit [celcius]
  (+ (/ (* 9 celcius) 5) 32))




                      © 2011 Howard M. Lewis Ship
'(1 2 "three")       List of values




(biggest 5 42)      Function call




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




                                            © 2011 Howard M. Lewis Ship
Read Eval Print Loop
       user=> (defn biggest
          "Find the maximum of two numbers"
          [x y]
          (if (> x y) x y))
       #=(var user/biggest)
       user=> (biggest 5 42)
       42
       user=> (doc biggest)
       -------------------------
       user/biggest
       ([x y])
          Find the maximum of two numbers
       nil
       user=> '(1 2 3)
       (1 2 3)
       user=> '(biggest 5 42)
       (biggest 5 42)
       user=> (first '(biggest 5 42))
       biggest
       user=> (eval '(biggest 5 42))
       42


                                              © 2011 Howard M. Lewis Ship
Source Code

Repl Input                 Clojure
                                   User Classes           Java
               Evaluator
                                                        Compiler
  Clojure
Source Files          Java Libraries

                            JVM

                    Operating System




                              23                  © 2011 Howard M. Lewis Ship
Simple Literals
• Strings
• Characters              user=> "A Clojure String"
                          "A Clojure String"
                          user=> space
• nil                     space
                          user=> A
• true                    A
                          user=> nil          nil is Java null

• false                   nil
                          user=> true
                          true
• integers                user=> false
                          false
• floating point numbers   user=> 0
                          0

• ratios                  user=> 2.5
                          2.5
                          user=> 22/7
                          22/7




                                                      © 2011 Howard M. Lewis Ship
Keywords
• Literal values
• Singleton instances
• Especially useful as map keys

            user=> (identical? :a-keyword :a-keyword)
            true
            user=> (str "a" "-" "string")
            "a-string"
            user=> (identical? "a-string" (str "a" "-" "string"))
            false
            user=> (keyword "a-keyword")
            :a-keyword
            user=> (identical? :a-keyword (keyword "a-keyword"))
            true




                                                             © 2011 Howard M. Lewis Ship
Lists

                             lst




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




                                       © 2011 Howard M. Lewis Ship
Lists

                              4
                                        lst


       conjoin: Add
      element to list
                                         1
 user=>   (conj lst 4)
 (4 1 2   3)
 user=>   (cons 4 lst)                        2
 (4 1 2   3)

                                                   3
                 construct: new seq
                with new first element


                                                  © 2011 Howard M. Lewis Ship
Vectors
 user=> (def v [:moe :larry :curly])
 #=(var user/v)
 user=> v
 [:moe :larry :curly]           first, rest and others
 user=> (first v)              work on lists, vectors or
 :moe                                   any seq
 user=> (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]




                                                           © 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"
                                     Keywords act as a function
 user=> (:first-name m)
 "Howard"                                that takes a map
 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




                                                           © 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")
 true
 user=> (contains? s "howard")
 false
 user=> (conj s "Howard")
 #{"Howard" "Jim" "Molly" "Suzanne"}
 user=> (conj s "Scott")
 #{"Howard" "Jim" "Molly" "Suzanne" "Scott"}




                                                      © 2011 Howard M. Lewis Ship
Functional
Programming
              © 2011 Howard M. Lewis Ship
My First Program

     10   X = 1
     20   PRINT X       "No it doesn't"
                      -- Miss Dimascio
     30   X = X + 1
     40   GOTO 20




                            © 2011 Howard M. Lewis Ship
Immutability
         © 2011 Howard M. Lewis Ship
function |ˈfə ng k sh ən|

noun
A 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).


                                      © 2011 Howard M. Lewis Ship
Predictable
        © 2011 Howard M. Lewis Ship
Isolation
From Time
       © 2011 Howard M. Lewis Ship
Inline anoymous
                             Java Interop
            function


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



          #(…) anonymous
              function


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



                            % anonymous
                             parameter


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")

                                                   © 2011 Howard M. Lewis Ship
Function as
          parameter


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



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


                              Function as
                              return value
                                                 ❝Closure
                                                  Oriented
(filter (require-extension "gz") names)
                                               Programming❞
     Composing
      functions

                                                          © 2011 Howard M. Lewis Ship
Java: Imperative Steps




                         © 2011 Howard M. Lewis Ship
Stock              Stock               Stock
         ticker: AAPL       ticker: MSFT       ticker: ORCL
      lastTrade: 203.25   lastTrade: 29.12   lastTrade: 21.90
        open: 204.50         open: 29.08        open: 21.83
          shares: 100         shares: 50         shares: 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;
}




                                                       © 2011 Howard M. Lewis Ship
Clojure: Flow of
Transformations




                   © 2011 Howard M. Lewis Ship
:ticker     AAPL             :ticker     MSFT           :ticker     ORCL


    :last-trade   203.25         :last-trade   29.12        :last-trade   21.90

{     :open       204.50   } {     :open       29.08   }{     :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)




                                                                   © 2011 Howard M. Lewis Ship
Laziness Is a Virtue




                       © 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)


                                                              © 2011 Howard M. Lewis Ship
© 2011 Howard M. Lewis Ship
La
                                    f




                                                                              zy
user=> (defn last-trade-value
          [stock]
          (* (:last-trade stock) (:shares stock)))
#'user/last-trade-value
user=> (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})




                                                             © 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.00M
user=> (reduce + 0 [])
0
user=> (reduce + nil)
0
                         Initial
                         Value




                                                     © 2011 Howard M. Lewis Ship
f
user=> (def input-string "Clojure is a fascinating language with unique
capabilities and total integration with Java.")
#'user/input-string
user=> (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}

                                                            © 2011 Howard M. Lewis Ship
List Comprehension




                                                                       La
                                                                          zy
  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])

                                                         © 2011 Howard M. Lewis Ship
❝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.❞

Paul Graham           © 2011 Howard M. Lewis Ship
Language
Ownership
            © 2011 Howard M. Lewis Ship
Who Owns The Java
Language?



     Brian Goetz    Mark Reinhold




                      © 2011 Howard M. Lewis Ship
Not You
      © 2011 Howard M. Lewis Ship
Source Code

Repl Input                 Clojure
                                  User Classes          Java
               Evaluator
                                                      Compiler
  Clojure
Source Files          Java Libraries

                            JVM

                    Operating System




                                                 © 2011 Howard M. Lewis Ship
Who Owns Clojure?




                    © 2011 Howard M. Lewis Ship
Clojure In Clojure




                     © 2011 Howard M. Lewis Ship
Short Circuiting
Evaluation
                  if (person.isPharaoh() &&
                                                      Dead Pharoahs
                      person.isDead() &&
                      buildPyramid(person)) {         get a Pyramid
                    person.entomb();
                  }



    boolean isPharoah = person.isPharoah();
    boolean isDead = person.isDead();
    boolean pyramidComplete = buildPyramid(person);         Everyone gets a
                                                               Pyramid!
    if (isPharoah && isDead && pyramidComplete) {
      person.entomb();
    }




                                                        © 2011 Howard M. Lewis Ship
(if                            Function invocation:
                (all-true                   evaluate all parameters
                  (.isPharaoh person)                 first
                  (.isDead person)
                  (build-pyramid person))
                (.entomb person))


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


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

    return true;
}
                              Java version of
                                 all-true

                                                  © 2011 Howard M. Lewis Ship
(if                           and  short-circuits, so
                         (and                         it's not a function
                           (.isPharaoh person)
                           (.isDead person)
                           (build-pyramid person))
                         (.entomb person))
       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


                                                           © 2011 Howard M. Lewis Ship
Caution: Head
Exploding Zone   © 2011 Howard M. Lewis Ship
Forms




           Vectors    Lists             Maps    Sets
Literals                                                      Function
            […]      '(1 2 3)           {…}    #{ … }           Calls,
"Hello"                                                        Special
  2.5                                                          Forms,
  nil                                                          Macros
                                                               (a b c)




                                                        © 2011 Howard M. Lewis Ship
If: Special Form
           user=> (doc if)
           -------------------------
           if
           Special Form
              Please see http://clojure.org/special_forms#if
           nil




 (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.
 …
                                                         © 2011 Howard M. Lewis Ship
Clojure Macros
     Reader




                   Macro
    Evaluator    Expansion




     Bytecode
    Generation




                             © 2011 Howard M. Lewis Ship
(if
                                                (if
  (and
                                                  (if (.isPharaoh person)
    (.isPharaoh person)
    (.isDead person)          Macro Expansion       (if (.isDead person)
                                                      (if (build-pyramid person)
    (build-pyramid person))
                                                        (.entomb person)))))
  (.entomb person))


                                                   Approximate
                                                expansion of macro




                                                              © 2011 Howard M. Lewis Ship
(defmacro and
                   ([] true)
                   ([x] x)
                   ([x & next]
                    `(let [and# ~x]
                       (if and# (and ~@next) and#))))



                                                        Evaluate
                                                  (.isPharaoh person)
                                                        only once
                                      (if
                                        (let [and_4422_auto (.isPharaoh person)]
(if
  (and              Macro Expansion       (if and_4422_auto
                                            (and
    (.isPharaoh person)
                                              (.isDead person)
    (.isDead person)
                                              (build-pyramid person))
    (build-pyramid person))
                                            and_4422_auto))
  (.entomb person))
                                        (.entomb person))




                                                                © 2011 Howard M. Lewis Ship
Code Forms




           Macro Expansion




def   if       let    fn     .   …


              Bytecode
             Generation


                                     © 2011 Howard M. Lewis Ship
Boilerplate
 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();
 }



          (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*")))))


                                                                       © 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))
               ])
           ]                                :html
       ]
  ])

                                        :head          :body


                               :title            :h1           :ul


                       "Cascade Blog"       "Cascade Blog"           (template-for …)
                                                                             © 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])))




                                     language from within
                  executable code




                                       Extend Clojure
                   Expand simple
                    placeholder to




                                          Clojure
(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)))))))

                                                            © 2011 Howard M. Lewis Ship
Wrap Up
          © 2011 Howard M. Lewis Ship
essence
noun
the intrinsic nature or indispensable quality of
something, esp. something abstract, that
determines its character : conflict is the essence of
drama.



                                           © 2011 Howard M. Lewis Ship
❝Controlling complexity is
    the essence of computer
         programming❞



Brian Kernigan         © 2011 Howard M. Lewis Ship
Control is the
  Essence of
Programming
          © 2011 Howard M. Lewis Ship
Evaluation
       © 2011 Howard M. Lewis Ship
Language or
 Language
  Toolkit?
        © 2011 Howard M. Lewis Ship
© 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
                                          http://www.clojure.org
• Impressive functional & concurrency
 support
• Most features not covered here




                                                   © 2011 Howard M. Lewis Ship
© 2011 Howard M. Lewis Ship
http://java.ociweb.com/mark/clojure/article.html




                                     © 2011 Howard M. Lewis Ship
http://tapestryjava.blogspot.com




                                   © 2011 Howard M. Lewis Ship
© 2011 Howard M. Lewis Ship
© 2011 Howard M. Lewis Ship
Image Credits
   © 2007 John Kannenberg
   http://www.flickr.com/photos/jkannenberg/541057337/
                                                       © 2008 Jonathan Ziapour
                      http://www.flickr.com/photos/jonathanziapour/2613204502/
   © 2008 Alexandre Pizzera
   http://www.flickr.com/photos/alecss/2563917055
                                                            © 2006 scott ogilvie
                               http://www.flickr.com/photos/scottog/100582274/
   © 2008 Ariel H.
   http://www.flickr.com/photos/fotosrotas/2730733412/
                                                   © 2008 Howard M. Lewis Ship
                                http://www.flickr.com/photos/hlship/3108306576
   © 2010 yuichi.sakuraba
   http://www.flickr.com/photos/skrb/5107280055
                                                                © 2007 Jon Fife
                                http://flickr.com/photos/good-karma/577632972/
   © Randall Munroe
   http://xkcd.com/297/
                                                         © 2008 Manu Gómez
                           http://www.flickr.com/photos/manugomi/2884678938/
   © 2008 Marcin Wichary
   http://www.flickr.com/photos/mwichary/2827326852/



                                                                     © 2011 Howard M. Lewis Ship
Image Credits
   © 2009 Howard M. Lewis Ship
   http://www.flickr.com/photos/hlship/3603090614/
                                                      © 2006 John Ryan Brubaker
                           http://www.flickr.com/photos/subconscience/297682093/
   © 2003 A. Lipson
   http://www.andrewlipson.com/escher/relativity.html
                                                                © 2007 Alan Chia
                              http://flickr.com/photos/seven13avenue/2080281038/

   © 2003 Randall Munroe
   http://xkcd.com/224/




                                                                     © 2011 Howard M. Lewis Ship

More Related Content

What's hot

Domain-Specific Languages for Composable Editor Plugins (LDTA 2009)
Domain-Specific Languages for Composable Editor Plugins (LDTA 2009)Domain-Specific Languages for Composable Editor Plugins (LDTA 2009)
Domain-Specific Languages for Composable Editor Plugins (LDTA 2009)
lennartkats
 

What's hot (20)

Cleaner APIs, Cleaner UIs with Visage (33rd Degrees)
Cleaner APIs, Cleaner UIs with Visage (33rd Degrees)Cleaner APIs, Cleaner UIs with Visage (33rd Degrees)
Cleaner APIs, Cleaner UIs with Visage (33rd Degrees)
 
Hacking JavaFX with Groovy, Clojure, Scala, and Visage: Stephen Chin
Hacking JavaFX with Groovy, Clojure, Scala, and Visage: Stephen ChinHacking JavaFX with Groovy, Clojure, Scala, and Visage: Stephen Chin
Hacking JavaFX with Groovy, Clojure, Scala, and Visage: Stephen Chin
 
Model-Driven Software Development - Pretty-Printing, Editor Services, Term Re...
Model-Driven Software Development - Pretty-Printing, Editor Services, Term Re...Model-Driven Software Development - Pretty-Printing, Editor Services, Term Re...
Model-Driven Software Development - Pretty-Printing, Editor Services, Term Re...
 
Domain-Specific Languages for Composable Editor Plugins (LDTA 2009)
Domain-Specific Languages for Composable Editor Plugins (LDTA 2009)Domain-Specific Languages for Composable Editor Plugins (LDTA 2009)
Domain-Specific Languages for Composable Editor Plugins (LDTA 2009)
 
ScalaDays 2014 - Reactive Scala 3D Game Engine
ScalaDays 2014 - Reactive Scala 3D Game Engine ScalaDays 2014 - Reactive Scala 3D Game Engine
ScalaDays 2014 - Reactive Scala 3D Game Engine
 
Scala in practice
Scala in practiceScala in practice
Scala in practice
 
G*ワークショップ in 仙台 Grails(とことん)入門
G*ワークショップ in 仙台 Grails(とことん)入門G*ワークショップ in 仙台 Grails(とことん)入門
G*ワークショップ in 仙台 Grails(とことん)入門
 
Cutting Edge Data Processing with PHP & XQuery
Cutting Edge Data Processing with PHP & XQueryCutting Edge Data Processing with PHP & XQuery
Cutting Edge Data Processing with PHP & XQuery
 
OSDC.fr 2012 :: Cascalog : progammation logique pour Hadoop
OSDC.fr 2012 :: Cascalog : progammation logique pour HadoopOSDC.fr 2012 :: Cascalog : progammation logique pour Hadoop
OSDC.fr 2012 :: Cascalog : progammation logique pour Hadoop
 
JDK Power Tools
JDK Power ToolsJDK Power Tools
JDK Power Tools
 
Статичный SQL в С++14. Евгений Захаров ➠ CoreHard Autumn 2019
Статичный SQL в С++14. Евгений Захаров ➠  CoreHard Autumn 2019Статичный SQL в С++14. Евгений Захаров ➠  CoreHard Autumn 2019
Статичный SQL в С++14. Евгений Захаров ➠ CoreHard Autumn 2019
 
Database security
Database securityDatabase security
Database security
 
Hack reduce mr-intro
Hack reduce mr-introHack reduce mr-intro
Hack reduce mr-intro
 
«Objective-C Runtime в примерах» — Алексей Сторожев, e-Legion
«Objective-C Runtime в примерах» — Алексей Сторожев, e-Legion«Objective-C Runtime в примерах» — Алексей Сторожев, e-Legion
«Objective-C Runtime в примерах» — Алексей Сторожев, e-Legion
 
Moving from JFreeChart to JavaFX with JavaFX Chart Extensions
Moving from JFreeChart to JavaFX with JavaFX Chart ExtensionsMoving from JFreeChart to JavaFX with JavaFX Chart Extensions
Moving from JFreeChart to JavaFX with JavaFX Chart Extensions
 
Doc Parsers Api Cheatsheet 1 0
Doc Parsers Api Cheatsheet 1 0Doc Parsers Api Cheatsheet 1 0
Doc Parsers Api Cheatsheet 1 0
 
Spock and Geb
Spock and GebSpock and Geb
Spock and Geb
 
Couchbase Korea User Group 2nd Meetup #2
Couchbase Korea User Group 2nd Meetup #2Couchbase Korea User Group 2nd Meetup #2
Couchbase Korea User Group 2nd Meetup #2
 
J slider
J sliderJ slider
J slider
 
Not your Grandma's XQuery
Not your Grandma's XQueryNot your Grandma's XQuery
Not your Grandma's XQuery
 

Viewers also liked

Ring: Web Apps in Idiomatic Clojure
Ring: Web Apps in Idiomatic ClojureRing: Web Apps in Idiomatic Clojure
Ring: Web Apps in Idiomatic Clojure
Mark McGranaghan
 
Messaging With Erlang And Jabber
Messaging With  Erlang And  JabberMessaging With  Erlang And  Jabber
Messaging With Erlang And Jabber
l xf
 
VoltDB and Erlang - Tech planet 2012
VoltDB and Erlang - Tech planet 2012VoltDB and Erlang - Tech planet 2012
VoltDB and Erlang - Tech planet 2012
Eonblast
 

Viewers also liked (20)

Ring: Web Apps in Idiomatic Clojure
Ring: Web Apps in Idiomatic ClojureRing: Web Apps in Idiomatic Clojure
Ring: Web Apps in Idiomatic Clojure
 
Introduction to clojure
Introduction to clojureIntroduction to clojure
Introduction to clojure
 
Using Clojure, NoSQL Databases and Functional-Style JavaScript to Write Gext-...
Using Clojure, NoSQL Databases and Functional-Style JavaScript to Write Gext-...Using Clojure, NoSQL Databases and Functional-Style JavaScript to Write Gext-...
Using Clojure, NoSQL Databases and Functional-Style JavaScript to Write Gext-...
 
Clojure: The Art of Abstraction
Clojure: The Art of AbstractionClojure: The Art of Abstraction
Clojure: The Art of Abstraction
 
From Callback Hell to Async Heaven - Promises!
From Callback Hell to Async Heaven - Promises!From Callback Hell to Async Heaven - Promises!
From Callback Hell to Async Heaven - Promises!
 
Embracing Clojure: a journey into Clojure adoption
Embracing Clojure: a journey into Clojure adoptionEmbracing Clojure: a journey into Clojure adoption
Embracing Clojure: a journey into Clojure adoption
 
穆黎森:Interactive batch query at scale
穆黎森:Interactive batch query at scale穆黎森:Interactive batch query at scale
穆黎森:Interactive batch query at scale
 
Clojure made-simple - John Stevenson
Clojure made-simple - John StevensonClojure made-simple - John Stevenson
Clojure made-simple - John Stevenson
 
What can be done with Java, but should better be done with Erlang (@pavlobaron)
What can be done with Java, but should better be done with Erlang (@pavlobaron)What can be done with Java, but should better be done with Erlang (@pavlobaron)
What can be done with Java, but should better be done with Erlang (@pavlobaron)
 
Messaging With Erlang And Jabber
Messaging With  Erlang And  JabberMessaging With  Erlang And  Jabber
Messaging With Erlang And Jabber
 
20 reasons why we don't need architects (@pavlobaron)
20 reasons why we don't need architects (@pavlobaron)20 reasons why we don't need architects (@pavlobaron)
20 reasons why we don't need architects (@pavlobaron)
 
High Performance Erlang
High  Performance  ErlangHigh  Performance  Erlang
High Performance Erlang
 
Clojure values
Clojure valuesClojure values
Clojure values
 
Clojure class
Clojure classClojure class
Clojure class
 
Winning the Erlang Edit•Build•Test Cycle
Winning the Erlang Edit•Build•Test CycleWinning the Erlang Edit•Build•Test Cycle
Winning the Erlang Edit•Build•Test Cycle
 
Erlang - Because s**t Happens by Mahesh Paolini-Subramanya
Erlang - Because s**t Happens by Mahesh Paolini-SubramanyaErlang - Because s**t Happens by Mahesh Paolini-Subramanya
Erlang - Because s**t Happens by Mahesh Paolini-Subramanya
 
Elixir talk
Elixir talkElixir talk
Elixir talk
 
VoltDB and Erlang - Tech planet 2012
VoltDB and Erlang - Tech planet 2012VoltDB and Erlang - Tech planet 2012
VoltDB and Erlang - Tech planet 2012
 
From Perl To Elixir
From Perl To ElixirFrom Perl To Elixir
From Perl To Elixir
 
NDC London 2014: Erlang Patterns Matching Business Needs
NDC London 2014: Erlang Patterns Matching Business NeedsNDC London 2014: Erlang Patterns Matching Business Needs
NDC London 2014: Erlang Patterns Matching Business Needs
 

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

Java EE 6 CDI Integrates with Spring & JSF
Java EE 6 CDI Integrates with Spring & JSFJava EE 6 CDI Integrates with Spring & JSF
Java EE 6 CDI Integrates with Spring & JSF
Jiayun Zhou
 

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

Modern Android Development - Epoxy
Modern Android Development - EpoxyModern Android Development - Epoxy
Modern Android Development - Epoxy
 
Fabio Collini - Async code on Kotlin: RxJava or/and coroutines - Codemotion M...
Fabio Collini - Async code on Kotlin: RxJava or/and coroutines - Codemotion M...Fabio Collini - Async code on Kotlin: RxJava or/and coroutines - Codemotion M...
Fabio Collini - Async code on Kotlin: RxJava or/and coroutines - Codemotion M...
 
JavaZone 2017 - The Hitchhiker’s guide to Java class reloading
JavaZone 2017 - The Hitchhiker’s guide to Java class reloadingJavaZone 2017 - The Hitchhiker’s guide to Java class reloading
JavaZone 2017 - The Hitchhiker’s guide to Java class reloading
 
Clojure And Swing
Clojure And SwingClojure And Swing
Clojure And Swing
 
JavaOne報告会 Java SE/JavaFX 編 - JJUG CCC 2010 Fall
JavaOne報告会 Java SE/JavaFX 編 - JJUG CCC 2010 FallJavaOne報告会 Java SE/JavaFX 編 - JJUG CCC 2010 Fall
JavaOne報告会 Java SE/JavaFX 編 - JJUG CCC 2010 Fall
 
Android Data Persistence
Android Data PersistenceAndroid Data Persistence
Android Data Persistence
 
EMFPath
EMFPathEMFPath
EMFPath
 
Counter Wars (JEEConf 2016)
Counter Wars (JEEConf 2016)Counter Wars (JEEConf 2016)
Counter Wars (JEEConf 2016)
 
Brew up a Rich Web Application with Cappuccino
Brew up a Rich Web Application with CappuccinoBrew up a Rich Web Application with Cappuccino
Brew up a Rich Web Application with Cappuccino
 
Hello, Is That FreeSWITCH? Then We're Coming to Check You!
Hello, Is That FreeSWITCH? Then We're Coming to Check You!Hello, Is That FreeSWITCH? Then We're Coming to Check You!
Hello, Is That FreeSWITCH? Then We're Coming to Check You!
 
Androsia: A step ahead in securing in-memory Android application data by Sami...
Androsia: A step ahead in securing in-memory Android application data by Sami...Androsia: A step ahead in securing in-memory Android application data by Sami...
Androsia: A step ahead in securing in-memory Android application data by Sami...
 
Lambdas and Streams Master Class Part 2
Lambdas and Streams Master Class Part 2Lambdas and Streams Master Class Part 2
Lambdas and Streams Master Class Part 2
 
NodeJS Spring style Inversifyjs
NodeJS Spring style InversifyjsNodeJS Spring style Inversifyjs
NodeJS Spring style Inversifyjs
 
T3chFest 2016 - The polyglot programmer
T3chFest 2016 - The polyglot programmerT3chFest 2016 - The polyglot programmer
T3chFest 2016 - The polyglot programmer
 
Android UI Development: Tips, Tricks, and Techniques
Android UI Development: Tips, Tricks, and TechniquesAndroid UI Development: Tips, Tricks, and Techniques
Android UI Development: Tips, Tricks, and Techniques
 
Android UI Tips, Tricks and Techniques
Android UI Tips, Tricks and TechniquesAndroid UI Tips, Tricks and Techniques
Android UI Tips, Tricks and Techniques
 
Java EE 6 CDI Integrates with Spring & JSF
Java EE 6 CDI Integrates with Spring & JSFJava EE 6 CDI Integrates with Spring & JSF
Java EE 6 CDI Integrates with Spring & JSF
 
Box2D with SIMD in JavaScript
Box2D with SIMD in JavaScriptBox2D with SIMD in JavaScript
Box2D with SIMD in JavaScript
 
Swift Ready for Production?
Swift Ready for Production?Swift Ready for Production?
Swift Ready for Production?
 
Kotlin: forse è la volta buona (Trento)
Kotlin: forse è la volta buona (Trento)Kotlin: forse è la volta buona (Trento)
Kotlin: forse è la volta buona (Trento)
 

More from Howard Lewis Ship

Have Your Cake and Eat It Too: Meta-Programming Techniques for Java
Have Your Cake and Eat It Too: Meta-Programming Techniques for JavaHave Your Cake and Eat It Too: Meta-Programming Techniques for Java
Have Your Cake and Eat It Too: Meta-Programming Techniques for Java
Howard Lewis Ship
 

More from Howard Lewis Ship (12)

Testing Web Applications with GEB
Testing Web Applications with GEBTesting Web Applications with GEB
Testing Web Applications with GEB
 
Spock: A Highly Logical Way To Test
Spock: A Highly Logical Way To TestSpock: A Highly Logical Way To Test
Spock: A Highly Logical Way To Test
 
Backbone.js: Run your Application Inside The Browser
Backbone.js: Run your Application Inside The BrowserBackbone.js: Run your Application Inside The Browser
Backbone.js: Run your Application Inside The Browser
 
Modern Application Foundations: Underscore and Twitter Bootstrap
Modern Application Foundations: Underscore and Twitter BootstrapModern Application Foundations: Underscore and Twitter Bootstrap
Modern Application Foundations: Underscore and Twitter Bootstrap
 
Have Your Cake and Eat It Too: Meta-Programming Techniques for Java
Have Your Cake and Eat It Too: Meta-Programming Techniques for JavaHave Your Cake and Eat It Too: Meta-Programming Techniques for Java
Have Your Cake and Eat It Too: Meta-Programming Techniques for Java
 
Arduino: Open Source Hardware Hacking from the Software Nerd Perspective
Arduino: Open Source Hardware Hacking from the Software Nerd PerspectiveArduino: Open Source Hardware Hacking from the Software Nerd Perspective
Arduino: Open Source Hardware Hacking from the Software Nerd Perspective
 
Practical Clojure Programming
Practical Clojure ProgrammingPractical Clojure Programming
Practical Clojure Programming
 
Codemash-Tapestry.pdf
Codemash-Tapestry.pdfCodemash-Tapestry.pdf
Codemash-Tapestry.pdf
 
Tapestry 5: Java Power, Scripting Ease
Tapestry 5: Java Power, Scripting EaseTapestry 5: Java Power, Scripting Ease
Tapestry 5: Java Power, Scripting Ease
 
Clojure Deep Dive
Clojure Deep DiveClojure Deep Dive
Clojure Deep Dive
 
Cascade
CascadeCascade
Cascade
 
Tapestry: State of the Union
Tapestry: State of the UnionTapestry: State of the Union
Tapestry: State of the Union
 

Recently uploaded

Recently uploaded (20)

Syngulon - Selection technology May 2024.pdf
Syngulon - Selection technology May 2024.pdfSyngulon - Selection technology May 2024.pdf
Syngulon - Selection technology May 2024.pdf
 
Powerful Start- the Key to Project Success, Barbara Laskowska
Powerful Start- the Key to Project Success, Barbara LaskowskaPowerful Start- the Key to Project Success, Barbara Laskowska
Powerful Start- the Key to Project Success, Barbara Laskowska
 
Speed Wins: From Kafka to APIs in Minutes
Speed Wins: From Kafka to APIs in MinutesSpeed Wins: From Kafka to APIs in Minutes
Speed Wins: From Kafka to APIs in Minutes
 
Linux Foundation Edge _ Overview of FDO Software Components _ Randy at Intel.pdf
Linux Foundation Edge _ Overview of FDO Software Components _ Randy at Intel.pdfLinux Foundation Edge _ Overview of FDO Software Components _ Randy at Intel.pdf
Linux Foundation Edge _ Overview of FDO Software Components _ Randy at Intel.pdf
 
SOQL 201 for Admins & Developers: Slice & Dice Your Org’s Data With Aggregate...
SOQL 201 for Admins & Developers: Slice & Dice Your Org’s Data With Aggregate...SOQL 201 for Admins & Developers: Slice & Dice Your Org’s Data With Aggregate...
SOQL 201 for Admins & Developers: Slice & Dice Your Org’s Data With Aggregate...
 
WebAssembly is Key to Better LLM Performance
WebAssembly is Key to Better LLM PerformanceWebAssembly is Key to Better LLM Performance
WebAssembly is Key to Better LLM Performance
 
ASRock Industrial FDO Solutions in Action for Industrial Edge AI _ Kenny at A...
ASRock Industrial FDO Solutions in Action for Industrial Edge AI _ Kenny at A...ASRock Industrial FDO Solutions in Action for Industrial Edge AI _ Kenny at A...
ASRock Industrial FDO Solutions in Action for Industrial Edge AI _ Kenny at A...
 
What's New in Teams Calling, Meetings and Devices April 2024
What's New in Teams Calling, Meetings and Devices April 2024What's New in Teams Calling, Meetings and Devices April 2024
What's New in Teams Calling, Meetings and Devices April 2024
 
How Red Hat Uses FDO in Device Lifecycle _ Costin and Vitaliy at Red Hat.pdf
How Red Hat Uses FDO in Device Lifecycle _ Costin and Vitaliy at Red Hat.pdfHow Red Hat Uses FDO in Device Lifecycle _ Costin and Vitaliy at Red Hat.pdf
How Red Hat Uses FDO in Device Lifecycle _ Costin and Vitaliy at Red Hat.pdf
 
IESVE for Early Stage Design and Planning
IESVE for Early Stage Design and PlanningIESVE for Early Stage Design and Planning
IESVE for Early Stage Design and Planning
 
UiPath Test Automation using UiPath Test Suite series, part 2
UiPath Test Automation using UiPath Test Suite series, part 2UiPath Test Automation using UiPath Test Suite series, part 2
UiPath Test Automation using UiPath Test Suite series, part 2
 
Choosing the Right FDO Deployment Model for Your Application _ Geoffrey at In...
Choosing the Right FDO Deployment Model for Your Application _ Geoffrey at In...Choosing the Right FDO Deployment Model for Your Application _ Geoffrey at In...
Choosing the Right FDO Deployment Model for Your Application _ Geoffrey at In...
 
Free and Effective: Making Flows Publicly Accessible, Yumi Ibrahimzade
Free and Effective: Making Flows Publicly Accessible, Yumi IbrahimzadeFree and Effective: Making Flows Publicly Accessible, Yumi Ibrahimzade
Free and Effective: Making Flows Publicly Accessible, Yumi Ibrahimzade
 
A Business-Centric Approach to Design System Strategy
A Business-Centric Approach to Design System StrategyA Business-Centric Approach to Design System Strategy
A Business-Centric Approach to Design System Strategy
 
IoT Analytics Company Presentation May 2024
IoT Analytics Company Presentation May 2024IoT Analytics Company Presentation May 2024
IoT Analytics Company Presentation May 2024
 
Where to Learn More About FDO _ Richard at FIDO Alliance.pdf
Where to Learn More About FDO _ Richard at FIDO Alliance.pdfWhere to Learn More About FDO _ Richard at FIDO Alliance.pdf
Where to Learn More About FDO _ Richard at FIDO Alliance.pdf
 
Enterprise Knowledge Graphs - Data Summit 2024
Enterprise Knowledge Graphs - Data Summit 2024Enterprise Knowledge Graphs - Data Summit 2024
Enterprise Knowledge Graphs - Data Summit 2024
 
Measures in SQL (a talk at SF Distributed Systems meetup, 2024-05-22)
Measures in SQL (a talk at SF Distributed Systems meetup, 2024-05-22)Measures in SQL (a talk at SF Distributed Systems meetup, 2024-05-22)
Measures in SQL (a talk at SF Distributed Systems meetup, 2024-05-22)
 
Buy Epson EcoTank L3210 Colour Printer Online.pptx
Buy Epson EcoTank L3210 Colour Printer Online.pptxBuy Epson EcoTank L3210 Colour Printer Online.pptx
Buy Epson EcoTank L3210 Colour Printer Online.pptx
 
THE BEST IPTV in GERMANY for 2024: IPTVreel
THE BEST IPTV in  GERMANY for 2024: IPTVreelTHE BEST IPTV in  GERMANY for 2024: IPTVreel
THE BEST IPTV in GERMANY for 2024: IPTVreel
 

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

  • 1. Clojure: Towards The Essence Of Programming Howard M. Lewis Ship © 2011 Howard M. Lewis Ship
  • 2. essence noun the intrinsic nature or indispensable quality of something, esp. something abstract, that determines its character : conflict is the essence of drama. © 2011 Howard M. Lewis Ship
  • 3. Applications Frameworks Libraries Language Operating System © 2011 Howard M. Lewis Ship
  • 4. Your code © 2011 Howard M. Lewis Ship
  • 5. Ceremony Vs. Essence © 2011 Howard M. Lewis Ship
  • 6. Is your language ... © 2011 Howard M. Lewis Ship
  • 7. … holding you back? © 2011 Howard M. Lewis Ship
  • 8. Stock Stock Stock ticker: AAPL ticker: MSFT ticker: ORCL lastTrade: 203.25 lastTrade: 29.12 lastTrade: 21.90 open: 204.50 open: 29.08 open: 21.83 shares: 100 shares: 50 shares: 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); } © 2011 Howard M. Lewis Ship
  • 9. :ticker AAPL :ticker MSFT :ticker ORCL :last-trade 203.25 :last-trade 29.12 :last-trade 21.90 { :open 204.50 } { :open 29.08 }{ :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-open user=> (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}) © 2011 Howard M. Lewis Ship
  • 10. Clojure: The Language © 2011 Howard M. Lewis Ship
  • 11. Aargh! (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) © 2011 Howard M. Lewis Ship
  • 12. (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)] Panic Ensues (.setContentType response "application/json") (with-open [writer (.getWriter response)] (binding [*out* writer] (print-json json-value)))) true) Ouch! © 2011 Howard M. Lewis Ship
  • 13. © 2011 Howard M. Lewis Ship
  • 14. defn render-json 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 © 2011 Howard M. Lewis Ship
  • 15. 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; } © 2011 Howard M. Lewis Ship
  • 16. (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)))) 24/234 true) 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; 24/375 } © 2011 Howard M. Lewis Ship
  • 17. public static float toFahrenheit(float celcius) { return 9 * celcius / 5 + 32; } High Low Precedence Precedence + (+ / 32 (/ (* 9 c) 5) * 5 32) 9 celcius © 2011 Howard M. Lewis Ship
  • 18. 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 17 public static toFahrenheit(F)F 0000010 6f 72 67 2f 65 78 61 6d 70 6c 65 2f 43 6f 6e 76 L0 0000020 65 72 73 69 6f 6e 73 07 00 04 01 00 0000030 61 2f 6c 61 6e 67 2f 4f 62 6a 65 63 10 74 6a 01 61 00 76 06 LINENUMBER 5 L0 0000040 3c 69 6e 69 74 3e 01 00 03 28 29 56 01 00 04 43 0000050 6f 64 65 0a 00 03 00 09 0c 00 05 00 06 01 00 0f LDC 9.0 0000060 4c 69 6e 65 4e 75 6d 62 65 72 54 61 62 6c 65 01 0000070 00 12 4c 6f 63 61 6c 56 61 72 69 61 62 6c 65 54 FLOAD 0 0000080 61 62 6c 65 01 00 04 74 68 69 73 01 00 19 4c 6f FMUL 0000090 72 67 2f 65 78 61 6d 70 6c 65 2f 43 6f 6e 76 65 00000a0 72 73 69 6f 6e 73 3b 01 00 0c 74 6f 46 61 68 72 LDC 5.0 00000b0 65 6e 68 65 69 74 01 00 04 28 46 29 46 04 41 10 00000c0 00 00 04 40 a0 00 00 04 42 00 00 00 01 00 07 63 FDIV 00000d0 65 6c 63 69 75 73 01 00 01 46 01 00 0a 53 6f 75 LDC 32.0 00000e0 72 63 65 46 69 6c 65 01 00 10 43 6f 00000f0 73 69 6f 6e 73 2e 6a 61 76 61 00 21 6e 00 76 01 65 00 72 03 FADD 0000100 00 00 00 00 00 02 00 01 00 05 00 06 00 01 00 07 0000110 00 00 00 2f 00 01 00 01 00 00 00 05 2a b7 00 08 FRETURN 0000120 b1 00 00 00 02 00 0a 00 00 00 06 00 01 00 00 00 0000130 03 00 0b 00 00 00 0c 00 01 00 00 00 05 00 0c 00 L1 0000140 0d 00 00 00 09 00 0e 00 0f 00 01 00 07 00 00 00 LOCALVARIABLE celcius F L0 L1 0 0000150 35 00 02 00 01 00 00 00 0b 12 10 22 6a 12 11 6e 0000160 12 12 62 ae 00 00 00 02 00 0a 00 00 00 06 00 01 MAXSTACK = 2 0000170 00 00 00 05 00 0b 00 00 00 0c 00 01 00 00 00 0b 0000180 00 13 00 14 00 00 00 01 00 15 00 00 00 02 00 16 MAXLOCALS = 1 0000190 © 2011 Howard M. Lewis Ship
  • 19. Clojure: Form Is Structure © 2011 Howard M. Lewis Ship
  • 20. (defn to-fahrenheit [celcius] (+ (/ (* 9 celcius) 5) 32)) © 2011 Howard M. Lewis Ship
  • 21. '(1 2 "three") List of values (biggest 5 42) Function call (defn biggest "Find the maximum of two numbers" Function [x y] definition (if (> x y) x y)) © 2011 Howard M. Lewis Ship
  • 22. Read Eval Print Loop user=> (defn biggest "Find the maximum of two numbers" [x y] (if (> x y) x y)) #=(var user/biggest) user=> (biggest 5 42) 42 user=> (doc biggest) ------------------------- user/biggest ([x y]) Find the maximum of two numbers nil user=> '(1 2 3) (1 2 3) user=> '(biggest 5 42) (biggest 5 42) user=> (first '(biggest 5 42)) biggest user=> (eval '(biggest 5 42)) 42 © 2011 Howard M. Lewis Ship
  • 23. Source Code Repl Input Clojure User Classes Java Evaluator Compiler Clojure Source Files Java Libraries JVM Operating System 23 © 2011 Howard M. Lewis Ship
  • 24. Simple Literals • Strings • Characters user=> "A Clojure String" "A Clojure String" user=> space • nil space user=> A • true A user=> nil nil is Java null • false nil user=> true true • integers user=> false false • floating point numbers user=> 0 0 • ratios user=> 2.5 2.5 user=> 22/7 22/7 © 2011 Howard M. Lewis Ship
  • 25. Keywords • Literal values • Singleton instances • Especially useful as map keys user=> (identical? :a-keyword :a-keyword) true user=> (str "a" "-" "string") "a-string" user=> (identical? "a-string" (str "a" "-" "string")) false user=> (keyword "a-keyword") :a-keyword user=> (identical? :a-keyword (keyword "a-keyword")) true © 2011 Howard M. Lewis Ship
  • 26. Lists lst user=> (def lst '(1 2 3)) #=(var user/lst) 1 user=> lst (1 2 3) user=> (first lst) 2 1 user=> (rest lst) (2 3) 3 © 2011 Howard M. Lewis Ship
  • 27. Lists 4 lst conjoin: Add element to list 1 user=> (conj lst 4) (4 1 2 3) user=> (cons 4 lst) 2 (4 1 2 3) 3 construct: new seq with new first element © 2011 Howard M. Lewis Ship
  • 28. Vectors user=> (def v [:moe :larry :curly]) #=(var user/v) user=> v [:moe :larry :curly] first, rest and others user=> (first v) work on lists, vectors or :moe any seq user=> (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] © 2011 Howard M. Lewis Ship
  • 29. 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" Keywords act as a function user=> (:first-name m) "Howard" that takes a map 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 © 2011 Howard M. Lewis Ship
  • 30. Sets user=> (def s #{"Howard" "Suzanne" "Molly" "Jim"}) #=(var user/s) user=> s #{"Howard" "Jim" "Molly" "Suzanne"} user=> (contains? s "Howard") true user=> (contains? s "howard") false user=> (conj s "Howard") #{"Howard" "Jim" "Molly" "Suzanne"} user=> (conj s "Scott") #{"Howard" "Jim" "Molly" "Suzanne" "Scott"} © 2011 Howard M. Lewis Ship
  • 31. Functional Programming © 2011 Howard M. Lewis Ship
  • 32. My First Program 10 X = 1 20 PRINT X "No it doesn't" -- Miss Dimascio 30 X = X + 1 40 GOTO 20 © 2011 Howard M. Lewis Ship
  • 33. Immutability © 2011 Howard M. Lewis Ship
  • 34. function |ˈfə ng k sh ən| noun A 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). © 2011 Howard M. Lewis Ship
  • 35. Predictable © 2011 Howard M. Lewis Ship
  • 36. Isolation From Time © 2011 Howard M. Lewis Ship
  • 37. Inline anoymous Java Interop function (filter (fn [name] (not (.startsWith name "."))) names) #(…) anonymous function (filter #(not (.startsWith % ".")) names) % anonymous parameter 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") © 2011 Howard M. Lewis Ship
  • 38. Function as parameter (filter #(not (.startsWith % ".")) names) (defn require-extension [ext] (fn [file-name] (= ext (last (split-string file-name "."))))) Function as return value ❝Closure Oriented (filter (require-extension "gz") names) Programming❞ Composing functions © 2011 Howard M. Lewis Ship
  • 39. Java: Imperative Steps © 2011 Howard M. Lewis Ship
  • 40. Stock Stock Stock ticker: AAPL ticker: MSFT ticker: ORCL lastTrade: 203.25 lastTrade: 29.12 lastTrade: 21.90 open: 204.50 open: 29.08 open: 21.83 shares: 100 shares: 50 shares: 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; } © 2011 Howard M. Lewis Ship
  • 41. Clojure: Flow of Transformations © 2011 Howard M. Lewis Ship
  • 42. :ticker AAPL :ticker MSFT :ticker ORCL :last-trade 203.25 :last-trade 29.12 :last-trade 21.90 { :open 204.50 } { :open 29.08 }{ :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) © 2011 Howard M. Lewis Ship
  • 43. Laziness Is a Virtue © 2011 Howard M. Lewis Ship
  • 44. 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) © 2011 Howard M. Lewis Ship
  • 45. © 2011 Howard M. Lewis Ship
  • 46. La f zy user=> (defn last-trade-value [stock] (* (:last-trade stock) (:shares stock))) #'user/last-trade-value user=> (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}) © 2011 Howard M. Lewis Ship
  • 47. f user=> (map last-trade-value portfolio) (20325.00M 1456.00M 4380.00M) user=> (reduce + (map last-trade-value portfolio)) 26161.00M user=> (reduce + 0 []) 0 user=> (reduce + nil) 0 Initial Value © 2011 Howard M. Lewis Ship
  • 48. f user=> (def input-string "Clojure is a fascinating language with unique capabilities and total integration with Java.") #'user/input-string user=> (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} © 2011 Howard M. Lewis Ship
  • 49. List Comprehension La zy 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]) © 2011 Howard M. Lewis Ship
  • 50. ❝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.❞ Paul Graham © 2011 Howard M. Lewis Ship
  • 51. Language Ownership © 2011 Howard M. Lewis Ship
  • 52. Who Owns The Java Language? Brian Goetz Mark Reinhold © 2011 Howard M. Lewis Ship
  • 53. Not You © 2011 Howard M. Lewis Ship
  • 54. Source Code Repl Input Clojure User Classes Java Evaluator Compiler Clojure Source Files Java Libraries JVM Operating System © 2011 Howard M. Lewis Ship
  • 55. Who Owns Clojure? © 2011 Howard M. Lewis Ship
  • 56. Clojure In Clojure © 2011 Howard M. Lewis Ship
  • 57. Short Circuiting Evaluation if (person.isPharaoh() && Dead Pharoahs person.isDead() && buildPyramid(person)) { get a Pyramid person.entomb(); } boolean isPharoah = person.isPharoah(); boolean isDead = person.isDead(); boolean pyramidComplete = buildPyramid(person); Everyone gets a Pyramid! if (isPharoah && isDead && pyramidComplete) { person.entomb(); } © 2011 Howard M. Lewis Ship
  • 58. (if Function invocation: (all-true evaluate all parameters (.isPharaoh person) first (.isDead person) (build-pyramid person)) (.entomb person)) (defn all-true ([] true) ([x] x) ([x & more] (if x (apply all-true more) x))) public static boolean allTrue(boolean... inputs) { for (boolean input : inputs) { if (!input) return false; } return true; } Java version of all-true © 2011 Howard M. Lewis Ship
  • 59. (if and short-circuits, so (and it's not a function (.isPharaoh person) (.isDead person) (build-pyramid person)) (.entomb person)) 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 © 2011 Howard M. Lewis Ship
  • 60. Caution: Head Exploding Zone © 2011 Howard M. Lewis Ship
  • 61. Forms Vectors Lists Maps Sets Literals Function […] '(1 2 3) {…} #{ … } Calls, "Hello" Special 2.5 Forms, nil Macros (a b c) © 2011 Howard M. Lewis Ship
  • 62. If: Special Form user=> (doc if) ------------------------- if Special Form Please see http://clojure.org/special_forms#if nil (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. … © 2011 Howard M. Lewis Ship
  • 63. Clojure Macros Reader Macro Evaluator Expansion Bytecode Generation © 2011 Howard M. Lewis Ship
  • 64. (if (if (and (if (.isPharaoh person) (.isPharaoh person) (.isDead person) Macro Expansion (if (.isDead person) (if (build-pyramid person) (build-pyramid person)) (.entomb person))))) (.entomb person)) Approximate expansion of macro © 2011 Howard M. Lewis Ship
  • 65. (defmacro and   ([] true)   ([x] x)   ([x & next]    `(let [and# ~x]       (if and# (and ~@next) and#)))) Evaluate (.isPharaoh person) only once (if (let [and_4422_auto (.isPharaoh person)] (if (and Macro Expansion (if and_4422_auto (and (.isPharaoh person) (.isDead person) (.isDead person) (build-pyramid person)) (build-pyramid person)) and_4422_auto)) (.entomb person)) (.entomb person)) © 2011 Howard M. Lewis Ship
  • 66. Code Forms Macro Expansion def if let fn . … Bytecode Generation © 2011 Howard M. Lewis Ship
  • 67. Boilerplate 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(); } (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*"))))) © 2011 Howard M. Lewis Ship
  • 68. 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)) ]) ] :html ] ]) :head :body :title :h1 :ul "Cascade Blog" "Cascade Blog" (template-for …) © 2011 Howard M. Lewis Ship
  • 69. (defn list-items [coll] (template (format "%d items" (count coll)) :ul {:class :item-list} [ (template-for [item coll] :li [item]))) language from within executable code Extend Clojure Expand simple placeholder to Clojure (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))))))) © 2011 Howard M. Lewis Ship
  • 70. Wrap Up © 2011 Howard M. Lewis Ship
  • 71. essence noun the intrinsic nature or indispensable quality of something, esp. something abstract, that determines its character : conflict is the essence of drama. © 2011 Howard M. Lewis Ship
  • 72. ❝Controlling complexity is the essence of computer programming❞ Brian Kernigan © 2011 Howard M. Lewis Ship
  • 73. Control is the Essence of Programming © 2011 Howard M. Lewis Ship
  • 74. Evaluation © 2011 Howard M. Lewis Ship
  • 75. Language or Language Toolkit? © 2011 Howard M. Lewis Ship
  • 76. © 2011 Howard M. Lewis Ship
  • 77. Clojure • 1.2 release: 19 Aug 2010 • Simple, regular syntax • Improves on Lisp: vectors, maps, sets • Fully integrates with Java http://www.clojure.org • Impressive functional & concurrency support • Most features not covered here © 2011 Howard M. Lewis Ship
  • 78. © 2011 Howard M. Lewis Ship
  • 79. http://java.ociweb.com/mark/clojure/article.html © 2011 Howard M. Lewis Ship
  • 80. http://tapestryjava.blogspot.com © 2011 Howard M. Lewis Ship
  • 81. © 2011 Howard M. Lewis Ship
  • 82. © 2011 Howard M. Lewis Ship
  • 83. Image Credits © 2007 John Kannenberg http://www.flickr.com/photos/jkannenberg/541057337/ © 2008 Jonathan Ziapour http://www.flickr.com/photos/jonathanziapour/2613204502/ © 2008 Alexandre Pizzera http://www.flickr.com/photos/alecss/2563917055 © 2006 scott ogilvie http://www.flickr.com/photos/scottog/100582274/ © 2008 Ariel H. http://www.flickr.com/photos/fotosrotas/2730733412/ © 2008 Howard M. Lewis Ship http://www.flickr.com/photos/hlship/3108306576 © 2010 yuichi.sakuraba http://www.flickr.com/photos/skrb/5107280055 © 2007 Jon Fife http://flickr.com/photos/good-karma/577632972/ © Randall Munroe http://xkcd.com/297/ © 2008 Manu Gómez http://www.flickr.com/photos/manugomi/2884678938/ © 2008 Marcin Wichary http://www.flickr.com/photos/mwichary/2827326852/ © 2011 Howard M. Lewis Ship
  • 84. Image Credits © 2009 Howard M. Lewis Ship http://www.flickr.com/photos/hlship/3603090614/ © 2006 John Ryan Brubaker http://www.flickr.com/photos/subconscience/297682093/ © 2003 A. Lipson http://www.andrewlipson.com/escher/relativity.html © 2007 Alan Chia http://flickr.com/photos/seven13avenue/2080281038/ © 2003 Randall Munroe http://xkcd.com/224/ © 2011 Howard M. Lewis Ship