Thanks to visit codestin.com
Credit goes to www.slideshare.net

Clojure

The LISP that makes the JVM dynamic




           http://clojure.org
What is Clojure?
Clojure is a dynamic, LISP-like programming
       language that runs on the JVM.
Clojure History

Started in 2007

Original author (and BDFL) Rich Hickey

Currently version 1.1 (1.2 expected within the next
month)

Available under Eclipse Public License

    “The Eclipse Public License is designed to be a
    business-friendly free software license and
    features weaker copyleft provisions than
    contemporary licenses such as the GNU General
    Public License (GPL).”
Defining features
LISP syntax

  Macros

Immutability

Functional programming

Concurrency
Java interoperability

REPL-based
Syntax
numbers - 1234
ratios - 22/7
strings - “foo”, “bar”

characters - a b c
symbols - foo, bar
keywords - :foo, :bar

boolean - true/false
null - nil
Syntax

Lists -   (1 2 3 4)


Vectors -     [1 2 3 4]


Maps -     {:a 1 :b 2 :c 3}   or   {:a 1, :b 2, :c 3}


Sets -    #{foo bar baz}
Syntax
               That’s it. There is no other syntax[1].

               Data structures are code.

               Homoiconic

               All data literals stand for themselves
               except:

                     Lists

                     Symbols
[1]: Technically, there are other special symbols for shortcutting syntax provided for the developer, but no other necessary syntax
Lists
(+ 1 1) ; => 2

(+ 1 2 3) ; => 6

(+ 1 2 (+ 3 4)) ; => 10

(class “foo”) ; => java.lang.String

(first [:a :b :c]) ; => :a

(rest ‘(“foo” “bar” “baz”)) ; => (“bar” “baz”)

   The ‘ tells the reader not to evaluate the first element as a function

   ‘(1 2 3) is shorthand for (quote (1 2 3))
Hello World
(ns helloworld)

(defn hello
  “An example function”
  [string]
  (println “Hello” string))

(hello “World”)   ; => “Hello World”
REPL demo
Operating on
       Collections
Collections are the main datastructure in
Clojure

A collection can be a list, a vector, a map or a
set

Some example collection functions:

  first, second, last, count, reverse, concat,
  conj, contains?, map, reduce, apply, filter,
  some, remove, every?, nth, into, doall,
  repeat, repeatedly, range,
Laziness
Sequences can be lazy, which allows them to be
infinite:
  (cycle [1 2 3]) ; => (1 2 3 1 2 3 1 2 3 ...)

  (repeat :a) ; => (:a :a :a :a :a :a :a ...)


When using lazy sequences, processing does not
occur until the sequence is realized.
  (class (repeat :a)) ; => clojure.lang.LazySeq


Realize (part of) a lazy sequence:
  (take 5 (repeat 42)) ; => (42 42 42 42 42)
More laziness

Can do neat things with infinite
sequences:
  (filter even? (iterate inc 1)) ; => (2 4 6 8...)


Lazily read lines from a file:
  (read-lines “/tmp/foo.txt”)


  Lines aren’t read until they are used in
  the returned list
Java interop
(.toLowerCase “EMC”) ; => “emc”


   (<method> <object> [<arg1> <arg2> ...])


(StringBuffer. “foo” ) ; => #<StringBuffer foo>


(Integer/parseInt “5”) ; => 5


(.contains “My spoon is too big.” “spoon“) ; => true


(javax.swing.JOptionPane/showMessageDialog nil "Sup!")




      “Clojure is a better Java than Java”
Java datastructures

Anything that’s a Collection (or array) in Java can easily be
treated (or converted) as a Clojure collection

   (first (.split “This is a sentence” “ “)) ; => “This”

   (import ‘java.util.ArrayList)
   (def foo (ArrayList. [1 2 3])) ; => #<ArrayList [1, 2, 3]>
   (seq foo) ; => (1 2 3)
   (vec foo) ; => [1 2 3]
More Java-interop
Type hints

   (defn #^String uppercase [#^String s] (.toUpperCase s))


Proxying Java classes

   (doto (javax.swing.JFrame.)
     (addKeyListener (proxy [java.awt.event.KeyListener] []
       (keyPressed [e] (println (.getKeyChar e) " key pressed"))
       (keyReleased [e] (println (.getKeyChar e) " key released"))
       (keyTyped [e] (println (.getKeyChar e) " key typed"))))
     (setVisible true))


Lots more

   gen-class, annotations, primitives, definterface, defprotocol
Immutability
    (defn add-age
      [person]
      (assoc person :age 10))

    (def timmy {:name “Timmy”})

    (print timmy)   ; => {:name “Timmy”}

    (add-age timmy) ; => {:name “Timmy”, :age 10}

    ; timmy never changes
    (print timmy)   ; => {:name “Timmy”}



Under the hood: 32-way trie trees. O(log32n)
Functional
       Programming
Functions are intended to be side-effect free
   They take values and return values

   Same argument, same result
   No notion of time

   Easy to add concurrency to the mix sanely
   Testing is easier because there is no state

Having no side effects isn’t always possible (io,
mutable java objects)
Concurrency
Locks are bad
Clojure’s defining concurrency feature is STM
   Gives you ACI out of ACID
       Atomicity
       Consistency
       Isolation
Immutability is what makes this possible
4 methods for changing data concurrently:
Dead-simple
        Concurrency
(def accounts [{:name   “Bob”   :balance   1000}
               {:name   “Sue”   :balance   2000}
               {:name   “Joe”   :balance   3000}
               {:name   “Ann”   :balance   4000}])

(defn add-interest
  [acct]
  (let [bal (:balance acct)]
    (Thread/sleep 1500)
    (assoc acct :balance (* bal 1.25))))

(time (doall (map add-interest accounts)))
; => "Elapsed time: 6001.023 msecs"

(time (doall (pmap add-interest accounts)))
; => "Elapsed time: 1519.73 msecs"
More simple
       concurrency
All functions defined in Clojure implement
Runnable:
  (defn dowork [] (println “doing work”))
  (.start (Thread. dowork)) ; => “doing work”


Access to all of Java’s concurrency stuff
(ThreadPoolExecutor, etc) with Java
interop
Concurrency (Refs)

   (def x (ref 100))
   @x ; => 100
   (def amounts [5 10 1 9 2])

   (defn dec-x
     [n]
     (dosync
       (alter x #(- % n))))

   (pmap dec-x amounts)
   @x ; => 73
Concurrency (Atoms)

    (def x (atom 100))
    @x ; => 100
    (def amounts [5 10 1 9 2])

    (defn dec-x
      [n]
      (swap! x #(- % n)))

    (pmap dec-x amounts)
    @x ; => 73
Concurrency (Agents)

   (def x (agent 0))
   @x ; => 0

   (defn increment [c n] (+ c n))

   (send x increment 5)   ; @x -> 5

   (send x increment 10) ; @x -> 15
Macros
(defmacro def-name-filter
  [n r]
  (let [docstring (str "Given a list of people maps, filter " n " in a list.")]
    `(defn ~n
       ~docstring
       [elements#]
       (filter (fn [t#] (re-find ~r (:name t#))) elements#))))

(def-name-filter foo-filter #"^foo")

(def people [{:name "pat"} {:name "foobar"} {:name "foo"} {:name "bar"}])

(doc foo-filter)
; => Given a list of people maps, filter foo-filter in a list.

(foo-filter people)
; => ({:name "foobar"} {:name "foo"})
Macroexpand example
List de-structuring
                                         ; Destructure in defn

                                         (defn print-items
                                           [item & rest]
; Destructure in let                       (println "item:" item)
                                           (println "rest:" rest)
(def my-list ‘([:a 1] [:b 2] [:c 3]))      (if-not (nil? rest)
                                             (apply print-items rest)))
(defn print-pair
  [pair]                                 (print-items 1 2 3 4 5)
  (let [[key val] pair]
     (println "key:" key "val:" val)))   item:   1
                                         rest:   (2 3 4 5)
(map print-pair my-list)                 item:   2
                                         rest:   (3 4 5)
key: :a val: 1                           item:   3
key: :b val: 2                           rest:   (4 5)
key: :c val: 3                           item:   4
                                         rest:   (5)
                                         item:   5
                                         rest:   nil
Much More
Polymorphism/multimethods
Pre and Post conditions for functions

Futures, Promises
Watchers

Bindings/Transients

Metadata features
Compilation

Clojure-in-Clojure
So much more!
More info

http://clojure.org

http://clojure.blip.tv

http://www.assembla.com/wiki/show/clojure/Getting_Started

#clojure on irc.freenode.net

Come talk to me about it!
Thanks!
 Questions?

Clojure Intro

  • 1.
    Clojure The LISP thatmakes the JVM dynamic http://clojure.org
  • 2.
    What is Clojure? Clojureis a dynamic, LISP-like programming language that runs on the JVM.
  • 3.
    Clojure History Started in2007 Original author (and BDFL) Rich Hickey Currently version 1.1 (1.2 expected within the next month) Available under Eclipse Public License “The Eclipse Public License is designed to be a business-friendly free software license and features weaker copyleft provisions than contemporary licenses such as the GNU General Public License (GPL).”
  • 4.
    Defining features LISP syntax Macros Immutability Functional programming Concurrency Java interoperability REPL-based
  • 5.
    Syntax numbers - 1234 ratios- 22/7 strings - “foo”, “bar” characters - a b c symbols - foo, bar keywords - :foo, :bar boolean - true/false null - nil
  • 6.
    Syntax Lists - (1 2 3 4) Vectors - [1 2 3 4] Maps - {:a 1 :b 2 :c 3} or {:a 1, :b 2, :c 3} Sets - #{foo bar baz}
  • 7.
    Syntax That’s it. There is no other syntax[1]. Data structures are code. Homoiconic All data literals stand for themselves except: Lists Symbols [1]: Technically, there are other special symbols for shortcutting syntax provided for the developer, but no other necessary syntax
  • 8.
    Lists (+ 1 1); => 2 (+ 1 2 3) ; => 6 (+ 1 2 (+ 3 4)) ; => 10 (class “foo”) ; => java.lang.String (first [:a :b :c]) ; => :a (rest ‘(“foo” “bar” “baz”)) ; => (“bar” “baz”) The ‘ tells the reader not to evaluate the first element as a function ‘(1 2 3) is shorthand for (quote (1 2 3))
  • 9.
    Hello World (ns helloworld) (defnhello “An example function” [string] (println “Hello” string)) (hello “World”) ; => “Hello World”
  • 10.
  • 11.
    Operating on Collections Collections are the main datastructure in Clojure A collection can be a list, a vector, a map or a set Some example collection functions: first, second, last, count, reverse, concat, conj, contains?, map, reduce, apply, filter, some, remove, every?, nth, into, doall, repeat, repeatedly, range,
  • 12.
    Laziness Sequences can belazy, which allows them to be infinite: (cycle [1 2 3]) ; => (1 2 3 1 2 3 1 2 3 ...) (repeat :a) ; => (:a :a :a :a :a :a :a ...) When using lazy sequences, processing does not occur until the sequence is realized. (class (repeat :a)) ; => clojure.lang.LazySeq Realize (part of) a lazy sequence: (take 5 (repeat 42)) ; => (42 42 42 42 42)
  • 13.
    More laziness Can doneat things with infinite sequences: (filter even? (iterate inc 1)) ; => (2 4 6 8...) Lazily read lines from a file: (read-lines “/tmp/foo.txt”) Lines aren’t read until they are used in the returned list
  • 14.
    Java interop (.toLowerCase “EMC”); => “emc” (<method> <object> [<arg1> <arg2> ...]) (StringBuffer. “foo” ) ; => #<StringBuffer foo> (Integer/parseInt “5”) ; => 5 (.contains “My spoon is too big.” “spoon“) ; => true (javax.swing.JOptionPane/showMessageDialog nil "Sup!") “Clojure is a better Java than Java”
  • 15.
    Java datastructures Anything that’sa Collection (or array) in Java can easily be treated (or converted) as a Clojure collection (first (.split “This is a sentence” “ “)) ; => “This” (import ‘java.util.ArrayList) (def foo (ArrayList. [1 2 3])) ; => #<ArrayList [1, 2, 3]> (seq foo) ; => (1 2 3) (vec foo) ; => [1 2 3]
  • 16.
    More Java-interop Type hints (defn #^String uppercase [#^String s] (.toUpperCase s)) Proxying Java classes (doto (javax.swing.JFrame.) (addKeyListener (proxy [java.awt.event.KeyListener] [] (keyPressed [e] (println (.getKeyChar e) " key pressed")) (keyReleased [e] (println (.getKeyChar e) " key released")) (keyTyped [e] (println (.getKeyChar e) " key typed")))) (setVisible true)) Lots more gen-class, annotations, primitives, definterface, defprotocol
  • 17.
    Immutability (defn add-age [person] (assoc person :age 10)) (def timmy {:name “Timmy”}) (print timmy) ; => {:name “Timmy”} (add-age timmy) ; => {:name “Timmy”, :age 10} ; timmy never changes (print timmy) ; => {:name “Timmy”} Under the hood: 32-way trie trees. O(log32n)
  • 18.
    Functional Programming Functions are intended to be side-effect free They take values and return values Same argument, same result No notion of time Easy to add concurrency to the mix sanely Testing is easier because there is no state Having no side effects isn’t always possible (io, mutable java objects)
  • 19.
    Concurrency Locks are bad Clojure’sdefining concurrency feature is STM Gives you ACI out of ACID Atomicity Consistency Isolation Immutability is what makes this possible 4 methods for changing data concurrently:
  • 20.
    Dead-simple Concurrency (def accounts [{:name “Bob” :balance 1000} {:name “Sue” :balance 2000} {:name “Joe” :balance 3000} {:name “Ann” :balance 4000}]) (defn add-interest [acct] (let [bal (:balance acct)] (Thread/sleep 1500) (assoc acct :balance (* bal 1.25)))) (time (doall (map add-interest accounts))) ; => "Elapsed time: 6001.023 msecs" (time (doall (pmap add-interest accounts))) ; => "Elapsed time: 1519.73 msecs"
  • 21.
    More simple concurrency All functions defined in Clojure implement Runnable: (defn dowork [] (println “doing work”)) (.start (Thread. dowork)) ; => “doing work” Access to all of Java’s concurrency stuff (ThreadPoolExecutor, etc) with Java interop
  • 22.
    Concurrency (Refs) (def x (ref 100)) @x ; => 100 (def amounts [5 10 1 9 2]) (defn dec-x [n] (dosync (alter x #(- % n)))) (pmap dec-x amounts) @x ; => 73
  • 23.
    Concurrency (Atoms) (def x (atom 100)) @x ; => 100 (def amounts [5 10 1 9 2]) (defn dec-x [n] (swap! x #(- % n))) (pmap dec-x amounts) @x ; => 73
  • 24.
    Concurrency (Agents) (def x (agent 0)) @x ; => 0 (defn increment [c n] (+ c n)) (send x increment 5) ; @x -> 5 (send x increment 10) ; @x -> 15
  • 25.
    Macros (defmacro def-name-filter [n r] (let [docstring (str "Given a list of people maps, filter " n " in a list.")] `(defn ~n ~docstring [elements#] (filter (fn [t#] (re-find ~r (:name t#))) elements#)))) (def-name-filter foo-filter #"^foo") (def people [{:name "pat"} {:name "foobar"} {:name "foo"} {:name "bar"}]) (doc foo-filter) ; => Given a list of people maps, filter foo-filter in a list. (foo-filter people) ; => ({:name "foobar"} {:name "foo"})
  • 26.
  • 27.
    List de-structuring ; Destructure in defn (defn print-items [item & rest] ; Destructure in let (println "item:" item) (println "rest:" rest) (def my-list ‘([:a 1] [:b 2] [:c 3])) (if-not (nil? rest) (apply print-items rest))) (defn print-pair [pair] (print-items 1 2 3 4 5) (let [[key val] pair] (println "key:" key "val:" val))) item: 1 rest: (2 3 4 5) (map print-pair my-list) item: 2 rest: (3 4 5) key: :a val: 1 item: 3 key: :b val: 2 rest: (4 5) key: :c val: 3 item: 4 rest: (5) item: 5 rest: nil
  • 28.
    Much More Polymorphism/multimethods Pre andPost conditions for functions Futures, Promises Watchers Bindings/Transients Metadata features Compilation Clojure-in-Clojure So much more!
  • 29.
  • 30.