Clojure




                   Clojure
          A practical LISP for the JVM


                          ¨
                Matthias Nußler

                m.nuessler@web.de


               February 1, 2011




                                         1 / 26
Clojure




Outline
          Introduction
          LISP
             LISP Quotes
          The Clojure Language
          Java Interoperability
             Calling Java from Clojure
             Calling Clojure from Java
          Concurrency
          IDE Support
          Questions & Answers
          Bibliography

                                         2 / 26
Clojure
   Introduction




What is Clojure?

          Clojure is
                  A fresh approach to LISP
                  A functional programming language
                  Created by Rich Hickey
                  Dynamically typed
                  Hosted on the Java Virtual Machine
                  Java interoperability is a design goal, rather than an
                  implementation detail
                  Strong concurrency semantics


                                                                           3 / 26
Clojure
   LISP




LISP

          LISt Processing (lists are a major data structure)
          Originally designed in 1958 by John McCarthy
          One of the oldest programming languages in existence
          (only Fortran is older)
          Once the favored programming language for AI research
          Based on lambda calculus
          Numerous LIPS dialects exist such as
              Scheme
              Common LISP
          “Lots of Irritating Superfluous Parentheses”?


                                                                  4 / 26
Clojure
   LISP
     LISP Quotes


LISP Quotes (1)



          “Lisp is worth learning for the profound enlightenment
          experience you will have when you finally get it; that experience
          will make you a better programmer for the rest of your days,
          even if you never actually use Lisp itself a lot.”
          –Eric Raymond: How to Become a Hacker


          “Lisp is a programmable programming language.”
          –John Foderaro: CACM, September 1991



                                                                             5 / 26
Clojure
   LISP
     LISP Quotes


LISP Quotes (2)


          “Greenspun’s Tenth Rule of Programming: any sufficiently
          complicated C or Fortran program contains an ad hoc
          informally-specified bug-ridden slow implementation of half of
          Common Lisp.”
          –Philip Greenspun


          “the greatest single programming language ever designed”
          –Alan Kay
          More quotes: http://www.paulgraham.com/quotes.html




                                                                          6 / 26
Clojure
   The Clojure Language




Clojure Language Basics
              “No syntax” :-)
              Prefix notation
              Lists are a core data structure in Clojure/LISP
              Code is written in the language’s own data-structures:
              (function param1 param2)
              Code as data philosophy
              Constants: Evaluate to themselves
              Symbols: Evaluate to the value bound to them (unless
              quoted)
              Bind a value to a symbol with def:
                     (def a-symbol 42) ; => #’user/a-symbol
                     a-symbol ; => 42
                     ’a-symbol ; => a-symbol
                                                                       7 / 26
Clojure
   The Clojure Language




Function definition


              fn creates an (anonymous) function object
                     Similar to lambda in Scheme (and Ruby)
                     (fn [x] (* x x))
                     Or even shorter using a macro: #(* %1 %1)
              Function object can be bound to a symbol
                     (def square (fn square [x] (* x x)))
                     (square 3) ; => 9
              Clojure provides a convenient shortcut
                     def plus fn → defn
                     (defn square [x] (* x x))



                                                                 8 / 26
Clojure
   The Clojure Language




Clojure Data Structures

          Data type       Example
          Numbers         1, 3.14, 3/4, ...
          Characters      a b c
          Strings         "a string" → Clojure strings are Java strings
          Regexps         #""
          Symbols         a b c
          Keywords        :default :key
          Lists           (1 2 3)
          Vectors         [1 2 3]
          Maps            {:a 1, :b 2, :c 3}
          Sets            #{"red" "green" "blue"}


                                                                          9 / 26
Clojure
   The Clojure Language




Higher Order Functions

          Higher order functions functions use functions as parameters or
          return values. Examples:
              every?
              filter
              map
              reduce
          Factorial using reduce
  1       (defn factorial [n]
  2         (let [ numbers ( range 1 (+ 1 n))]
  3           ( reduce * numbers )))



                                                                            10 / 26
Clojure
   Java Interoperability




Interoperability Overview

          With Clojure it is possible to
                Create instances of Java classes
                Invoke instance methods
                Invoke static methods on Java classes
                Implement Java interfaces, extend classes
                Generate Java classes and interfaces
                Compile Clojure code to Java byte code
                Call Clojure from Java
          → Access to thousands of Java libraries and frameworks


                                                                   11 / 26
Clojure
   Java Interoperability
      Calling Java from Clojure


Creating Instances



          Using the new special form

  1       ( import ’(java.text SimpleDateFormat ))
  2       (def sdf (new SimpleDateFormat " yyyy-MM-dd "))


          Shorter with dot notation
  3       (def sdf ( SimpleDateFormat . " yyyy-MM-dd "))




                                                            12 / 26
Clojure
   Java Interoperability
      Calling Java from Clojure


Member Access
          Invoking an instance method
  1       (defn date-from-string [ date-string ]
  2         (let [sdf ( SimpleDateFormat . " yyyy-MM-dd ")]
  3           (. parse sdf date-string )))


          Accessing a field
  4       (def point (java.awt. Point . 10 20))
  5       (.x point ) ; => 10


          Invoking static methods
  6       (Long/ parseLong " 12321 ")
  7       ( Thread / sleep 3000)

                                                              13 / 26
Clojure
   Java Interoperability
      Calling Java from Clojure


Method chaining



          Method chaining using dot-dot notation
  1       (.. ( Calendar / getInstance ) getTimeZone getDisplayName )


          That is equivalent to the following Java code
  2       Calendar . getInstance (). getTimezone ()
  3         . getDisplayName ();




                                                                   14 / 26
Clojure
   Java Interoperability
      Calling Java from Clojure


Calling multiple methods on a Java object


          Long version
  1       ( import ’(java.util Calendar ))
  2       (defn the-past-midnight-1 []
  3          (let [ calendar-obj ( Calendar / getInstance )]
  4            (. set calendar-obj Calendar / AM_PM Calendar /AM)
  5            (. set calendar-obj Calendar /HOUR 0)
  6            (. set calendar-obj Calendar / MINUTE 0)
  7            (. set calendar-obj Calendar / SECOND 0)
  8            (. set calendar-obj Calendar / MILLISECOND 0)
  9            (. getTime calendar-obj )))




                                                                    15 / 26
Clojure
   Java Interoperability
      Calling Java from Clojure


Calling multiple methods on a Java object


          Shorter using the doto macro

  1       (defn the-past-midnight-2 []
  2         (let [ calendar-obj ( Calendar / getInstance )]
  3           (doto calendar-obj
  4              (. set Calendar / AM_PM Calendar /AM)
  5              (. set Calendar /HOUR 0)
  6              (. set Calendar / MINUTE 0)
  7              (. set Calendar / SECOND 0)
  8              (. set Calendar / MILLISECOND 0))
  9           (. getTime calendar-obj )))




                                                              16 / 26
Clojure
   Java Interoperability
      Calling Java from Clojure


Implementing interfaces / extending classes



          With proxy

  1       (defn action-listener [idx frei buttons ]
  2         (proxy [java.awt. event . ActionListener ] []
  3           ( actionPerformed [e]
  4              (...))))




                                                            17 / 26
Clojure
   Java Interoperability
      Calling Clojure from Java


Calling Clojure from Java


  1       import clojure .lang.RT;
  2       import clojure .lang.Var;
  3
  4       public class Driver {
  5         public static void main( String [] args) throws Exceptio
  6           RT. loadResourceScript (" clojure_script .clj");
  7           Var report = RT.var("clj. script . examples ", " print-re
  8           Integer result = ( Integer ) report . invoke ("Siva");
  9           System .out. println ("[Java]    Result : " + result );
 10         }
 11       }



                                                                  18 / 26
Clojure
   Concurrency




Clojure’s Approach to Concurrency


             Immutable objects
             Persistent data-structures (preserve the previous version
             of themselves when modfied)
             Managed references (4 different kinds)
             Clojure programs are guaranteed not to deadlock
             Software Transactional Memory (STM) system
                 has ACI properties: atomicity, consistency, isolation (no
                 durability)
                 implements multiversion concurrency control (MVCC)




                                                                             19 / 26
Clojure
   Concurrency




Managed References



          Ref. type   Useful for
          ref         shared changes, synchronous, coordinated changes
          agent       shared changes, asynchronous, independent changes
          atom        shared changes, synchronous, independent changes
          var         isolated changes




                                                                    20 / 26
Clojure
   Concurrency




Refs, Agents, Atoms, Vars (1)


          Refs
             A ref holds a value that can be changed in a synchronous
             and coordinated manner
             Creating a ref: (def all-users (ref {}))
             Dereferencing a ref: (deref all-users)
             Mutating a ref using the ref-set, alter or commute
             functions
                 (ref-set all-users {})
                 STM transaction required!
                 Correct way: (dosync (ref-set all-users {}))



                                                                        21 / 26
Clojure
   Concurrency




Refs, Agents, Atoms, Vars (2)

          Agents
             Allow for asynchronous and independent changes to
             shared mutable data
             Hold values that can be changed using special functions
             (asynchronously, at some point in the future)

          Atoms
             Allow for synchronous and independent changes to
             mutable data
             Atoms are updated synchronously (immediately).


                                                                       22 / 26
Clojure
   Concurrency




Refs, Agents, Atoms, Vars (2)

          Agents
             Allow for asynchronous and independent changes to
             shared mutable data
             Hold values that can be changed using special functions
             (asynchronously, at some point in the future)

          Atoms
             Allow for synchronous and independent changes to
             mutable data
             Atoms are updated synchronously (immediately).


                                                                       22 / 26
Clojure
   Concurrency




Refs, Agents, Atoms, Vars (3)




          Vars
             Can be thought of as pointers to mutable storage locations,
             which can be updated on a per- thread basis
             Similar to java.lang.ThreadLocal




                                                                           23 / 26
Clojure
   IDE Support




IDE Support

                 Eclipse: Counterclockwise
                       http://code.google.com/p/counterclockwise/
                 IntelliJ IDEA: La Clojure
                       http://plugins.intellij.net/plugin/?id=4050
                 Netbeans: Enclojure
                       http://www.enclojure.org/
                 Emacs
                 Vim
                 Textmate
                 ...


                                                                     24 / 26
Clojure
   Questions & Answers




Questions?




          Source: http://xkcd.com/224/




                                         25 / 26
Clojure
   Bibliography




Bibliography




          Rathore, Amit: Clojure in Action
          MEAP Edition, Manning Publications, 2010

          Neppert, Burkhard: Clojure unter der Lupe
          Javamagazin 2/2011, Software & Support
          Media GmbH




                                                      26 / 26

Clojure - A practical LISP for the JVM

  • 1.
    Clojure Clojure A practical LISP for the JVM ¨ Matthias Nußler m.nuessler@web.de February 1, 2011 1 / 26
  • 2.
    Clojure Outline Introduction LISP LISP Quotes The Clojure Language Java Interoperability Calling Java from Clojure Calling Clojure from Java Concurrency IDE Support Questions & Answers Bibliography 2 / 26
  • 3.
    Clojure Introduction What is Clojure? Clojure is A fresh approach to LISP A functional programming language Created by Rich Hickey Dynamically typed Hosted on the Java Virtual Machine Java interoperability is a design goal, rather than an implementation detail Strong concurrency semantics 3 / 26
  • 4.
    Clojure LISP LISP LISt Processing (lists are a major data structure) Originally designed in 1958 by John McCarthy One of the oldest programming languages in existence (only Fortran is older) Once the favored programming language for AI research Based on lambda calculus Numerous LIPS dialects exist such as Scheme Common LISP “Lots of Irritating Superfluous Parentheses”? 4 / 26
  • 5.
    Clojure LISP LISP Quotes LISP Quotes (1) “Lisp is worth learning for the profound enlightenment experience you will have when you finally get it; that experience will make you a better programmer for the rest of your days, even if you never actually use Lisp itself a lot.” –Eric Raymond: How to Become a Hacker “Lisp is a programmable programming language.” –John Foderaro: CACM, September 1991 5 / 26
  • 6.
    Clojure LISP LISP Quotes LISP Quotes (2) “Greenspun’s Tenth Rule of Programming: any sufficiently complicated C or Fortran program contains an ad hoc informally-specified bug-ridden slow implementation of half of Common Lisp.” –Philip Greenspun “the greatest single programming language ever designed” –Alan Kay More quotes: http://www.paulgraham.com/quotes.html 6 / 26
  • 7.
    Clojure The Clojure Language Clojure Language Basics “No syntax” :-) Prefix notation Lists are a core data structure in Clojure/LISP Code is written in the language’s own data-structures: (function param1 param2) Code as data philosophy Constants: Evaluate to themselves Symbols: Evaluate to the value bound to them (unless quoted) Bind a value to a symbol with def: (def a-symbol 42) ; => #’user/a-symbol a-symbol ; => 42 ’a-symbol ; => a-symbol 7 / 26
  • 8.
    Clojure The Clojure Language Function definition fn creates an (anonymous) function object Similar to lambda in Scheme (and Ruby) (fn [x] (* x x)) Or even shorter using a macro: #(* %1 %1) Function object can be bound to a symbol (def square (fn square [x] (* x x))) (square 3) ; => 9 Clojure provides a convenient shortcut def plus fn → defn (defn square [x] (* x x)) 8 / 26
  • 9.
    Clojure The Clojure Language Clojure Data Structures Data type Example Numbers 1, 3.14, 3/4, ... Characters a b c Strings "a string" → Clojure strings are Java strings Regexps #"" Symbols a b c Keywords :default :key Lists (1 2 3) Vectors [1 2 3] Maps {:a 1, :b 2, :c 3} Sets #{"red" "green" "blue"} 9 / 26
  • 10.
    Clojure The Clojure Language Higher Order Functions Higher order functions functions use functions as parameters or return values. Examples: every? filter map reduce Factorial using reduce 1 (defn factorial [n] 2 (let [ numbers ( range 1 (+ 1 n))] 3 ( reduce * numbers ))) 10 / 26
  • 11.
    Clojure Java Interoperability Interoperability Overview With Clojure it is possible to Create instances of Java classes Invoke instance methods Invoke static methods on Java classes Implement Java interfaces, extend classes Generate Java classes and interfaces Compile Clojure code to Java byte code Call Clojure from Java → Access to thousands of Java libraries and frameworks 11 / 26
  • 12.
    Clojure Java Interoperability Calling Java from Clojure Creating Instances Using the new special form 1 ( import ’(java.text SimpleDateFormat )) 2 (def sdf (new SimpleDateFormat " yyyy-MM-dd ")) Shorter with dot notation 3 (def sdf ( SimpleDateFormat . " yyyy-MM-dd ")) 12 / 26
  • 13.
    Clojure Java Interoperability Calling Java from Clojure Member Access Invoking an instance method 1 (defn date-from-string [ date-string ] 2 (let [sdf ( SimpleDateFormat . " yyyy-MM-dd ")] 3 (. parse sdf date-string ))) Accessing a field 4 (def point (java.awt. Point . 10 20)) 5 (.x point ) ; => 10 Invoking static methods 6 (Long/ parseLong " 12321 ") 7 ( Thread / sleep 3000) 13 / 26
  • 14.
    Clojure Java Interoperability Calling Java from Clojure Method chaining Method chaining using dot-dot notation 1 (.. ( Calendar / getInstance ) getTimeZone getDisplayName ) That is equivalent to the following Java code 2 Calendar . getInstance (). getTimezone () 3 . getDisplayName (); 14 / 26
  • 15.
    Clojure Java Interoperability Calling Java from Clojure Calling multiple methods on a Java object Long version 1 ( import ’(java.util Calendar )) 2 (defn the-past-midnight-1 [] 3 (let [ calendar-obj ( Calendar / getInstance )] 4 (. set calendar-obj Calendar / AM_PM Calendar /AM) 5 (. set calendar-obj Calendar /HOUR 0) 6 (. set calendar-obj Calendar / MINUTE 0) 7 (. set calendar-obj Calendar / SECOND 0) 8 (. set calendar-obj Calendar / MILLISECOND 0) 9 (. getTime calendar-obj ))) 15 / 26
  • 16.
    Clojure Java Interoperability Calling Java from Clojure Calling multiple methods on a Java object Shorter using the doto macro 1 (defn the-past-midnight-2 [] 2 (let [ calendar-obj ( Calendar / getInstance )] 3 (doto calendar-obj 4 (. set Calendar / AM_PM Calendar /AM) 5 (. set Calendar /HOUR 0) 6 (. set Calendar / MINUTE 0) 7 (. set Calendar / SECOND 0) 8 (. set Calendar / MILLISECOND 0)) 9 (. getTime calendar-obj ))) 16 / 26
  • 17.
    Clojure Java Interoperability Calling Java from Clojure Implementing interfaces / extending classes With proxy 1 (defn action-listener [idx frei buttons ] 2 (proxy [java.awt. event . ActionListener ] [] 3 ( actionPerformed [e] 4 (...)))) 17 / 26
  • 18.
    Clojure Java Interoperability Calling Clojure from Java Calling Clojure from Java 1 import clojure .lang.RT; 2 import clojure .lang.Var; 3 4 public class Driver { 5 public static void main( String [] args) throws Exceptio 6 RT. loadResourceScript (" clojure_script .clj"); 7 Var report = RT.var("clj. script . examples ", " print-re 8 Integer result = ( Integer ) report . invoke ("Siva"); 9 System .out. println ("[Java] Result : " + result ); 10 } 11 } 18 / 26
  • 19.
    Clojure Concurrency Clojure’s Approach to Concurrency Immutable objects Persistent data-structures (preserve the previous version of themselves when modfied) Managed references (4 different kinds) Clojure programs are guaranteed not to deadlock Software Transactional Memory (STM) system has ACI properties: atomicity, consistency, isolation (no durability) implements multiversion concurrency control (MVCC) 19 / 26
  • 20.
    Clojure Concurrency Managed References Ref. type Useful for ref shared changes, synchronous, coordinated changes agent shared changes, asynchronous, independent changes atom shared changes, synchronous, independent changes var isolated changes 20 / 26
  • 21.
    Clojure Concurrency Refs, Agents, Atoms, Vars (1) Refs A ref holds a value that can be changed in a synchronous and coordinated manner Creating a ref: (def all-users (ref {})) Dereferencing a ref: (deref all-users) Mutating a ref using the ref-set, alter or commute functions (ref-set all-users {}) STM transaction required! Correct way: (dosync (ref-set all-users {})) 21 / 26
  • 22.
    Clojure Concurrency Refs, Agents, Atoms, Vars (2) Agents Allow for asynchronous and independent changes to shared mutable data Hold values that can be changed using special functions (asynchronously, at some point in the future) Atoms Allow for synchronous and independent changes to mutable data Atoms are updated synchronously (immediately). 22 / 26
  • 23.
    Clojure Concurrency Refs, Agents, Atoms, Vars (2) Agents Allow for asynchronous and independent changes to shared mutable data Hold values that can be changed using special functions (asynchronously, at some point in the future) Atoms Allow for synchronous and independent changes to mutable data Atoms are updated synchronously (immediately). 22 / 26
  • 24.
    Clojure Concurrency Refs, Agents, Atoms, Vars (3) Vars Can be thought of as pointers to mutable storage locations, which can be updated on a per- thread basis Similar to java.lang.ThreadLocal 23 / 26
  • 25.
    Clojure IDE Support IDE Support Eclipse: Counterclockwise http://code.google.com/p/counterclockwise/ IntelliJ IDEA: La Clojure http://plugins.intellij.net/plugin/?id=4050 Netbeans: Enclojure http://www.enclojure.org/ Emacs Vim Textmate ... 24 / 26
  • 26.
    Clojure Questions & Answers Questions? Source: http://xkcd.com/224/ 25 / 26
  • 27.
    Clojure Bibliography Bibliography Rathore, Amit: Clojure in Action MEAP Edition, Manning Publications, 2010 Neppert, Burkhard: Clojure unter der Lupe Javamagazin 2/2011, Software & Support Media GmbH 26 / 26