Clojure Intro

T
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?
1 of 30

More Related Content

What's hot(20)

A look into the sanitizer family (ASAN & UBSAN) by Akul PillaiA look into the sanitizer family (ASAN & UBSAN) by Akul Pillai
A look into the sanitizer family (ASAN & UBSAN) by Akul Pillai
Cysinfo Cyber Security Community1.5K views
Domain AdaptationDomain Adaptation
Domain Adaptation
Mark Chang725 views
Multi verse optimizationMulti verse optimization
Multi verse optimization
Anuja Joshi1.5K views
Lec 4,5Lec 4,5
Lec 4,5
alaa2231.2K views

Similar to Clojure Intro

(first '(Clojure.))(first '(Clojure.))
(first '(Clojure.))niklal
458 views57 slides
Introduction to clojureIntroduction to clojure
Introduction to clojureAbbas Raza
1.4K views72 slides

Similar to Clojure Intro(20)

Pune Clojure Course OutlinePune Clojure Course Outline
Pune Clojure Course Outline
Baishampayan Ghose686 views
(first '(Clojure.))(first '(Clojure.))
(first '(Clojure.))
niklal458 views
Getting started with ClojureGetting started with Clojure
Getting started with Clojure
John Stevenson1.7K views
Exploring ClojurescriptExploring Clojurescript
Exploring Clojurescript
Luke Donnet83 views
Full Stack ClojureFull Stack Clojure
Full Stack Clojure
Michiel Borkent2K views
Introduction to clojureIntroduction to clojure
Introduction to clojure
Abbas Raza1.4K views
Hw09   Hadoop + ClojureHw09   Hadoop + Clojure
Hw09 Hadoop + Clojure
Cloudera, Inc.1.3K views
Hadoop + ClojureHadoop + Clojure
Hadoop + Clojure
elliando dias1.6K views
Clojure for Java developers - StockholmClojure for Java developers - Stockholm
Clojure for Java developers - Stockholm
Jan Kronquist1.7K views
(map Clojure everyday-tasks)(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
Jacek Laskowski1.6K views
Clojure 1.1 And BeyondClojure 1.1 And Beyond
Clojure 1.1 And Beyond
Mike Fogus1.1K views
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with Clojure
Dmitry Buzdin3.5K views
Clojure made simple - Lightning talkClojure made simple - Lightning talk
Clojure made simple - Lightning talk
John Stevenson750 views
ClojureScript for the webClojureScript for the web
ClojureScript for the web
Michiel Borkent758 views
Clojure入門Clojure入門
Clojure入門
Naoyuki Kakuda5K views
Clojure And SwingClojure And Swing
Clojure And Swing
Skills Matter3.6K views
The Curious Clojurist - Neal Ford (Thoughtworks)The Curious Clojurist - Neal Ford (Thoughtworks)
The Curious Clojurist - Neal Ford (Thoughtworks)
jaxLondonConference2.4K views

Recently uploaded(20)

ChatGPT and AI for Web DevelopersChatGPT and AI for Web Developers
ChatGPT and AI for Web Developers
Maximiliano Firtman152 views
CXL at OCPCXL at OCP
CXL at OCP
CXL Forum183 views
Web Dev - 1 PPT.pdfWeb Dev - 1 PPT.pdf
Web Dev - 1 PPT.pdf
gdsczhcet48 views

Clojure Intro

  • 1. Clojure The LISP that makes the JVM dynamic http://clojure.org
  • 2. What is Clojure? Clojure is a dynamic, LISP-like programming language that runs on the JVM.
  • 3. 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).”
  • 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) (defn hello “An example function” [string] (println “Hello” string)) (hello “World”) ; => “Hello World”
  • 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 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)
  • 13. 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
  • 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’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]
  • 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’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:
  • 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"})
  • 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 and Post conditions for functions Futures, Promises Watchers Bindings/Transients Metadata features Compilation Clojure-in-Clojure So much more!

Editor's Notes