Why Clojure?
1. How many processors does the machine have? How many does your program use? How many would you like to use?2. Author stipulates mutable objects are the new spaghetti code. Concurrency is difficult in Java. Java allows direct references to mutable objects. Clojure makes concurrency easier since it allows only indirect references to immutable objects (only references mutate).
Features of Clojure
- Concurrent programming based on immutable data structures- Software Transactional Memory takes care of the hard parts of concurrent programming
- Meta-programming
- Functional programming
- Object support
- Java interoperability
Clojure implements hairy locking code so you don't have to. Example - multiple cells on the screen, multiple ants searching the cells for food, only one ant per cell, ants mark cells with pheromones (which evaporate) which lead other ants to the food which they can pick up and take home. Many simultaneous processes. Lots of contention.
Documentation
A free download of the 2005 book Practical Common Lisp is available at Apress.The project website.
The wikipedia article
The extremely helpful wikibooks entry. Stuart Halloway's blog is a great reference, too.
High quality video presentations by Clojure's creator are available as iTunes podcasts.
Traditional Lisp
LispWorks provides a Lisp execution environment for Windows and Mac. LispWorks provides the HyperSpec. LispWorks does not use Clojure or easily interoperate with Java.(new java.util.Date)
works in Clojure but not in LispWorks. You can see how much better Clojure is. Installing and Running Clojure
The following steps are sufficient to get Clojure running on your system. The Clojure entry in wikibooks gives additional details. Subversion access to Clojure's code is documented at http://sourceforge.net/svn/?group_id=137961. Clojure compiles and runs like any other Java project. First, download the project.dev> svn co https://clojure.svn.sourceforge.net/svnroot/clojure clojure
After acquiring the code, change directory to the trunk folder and execute maven.
dev> cd clojure/trunk
trunk> mvn install
Now, run it.
trunk> cd target
target> java -cp clojure-lang-1.0-SNAPSHOT.jar clojure.lang.Repl
or, if you have jline ( very helpful command line utility),
target> java -cp .:../../lib/jline-0.9.94.jar:clojure-lang-1.0-SNAPSHOT.jar jline.ConsoleRunner clojure.lang.Repl
Comparison to Java
Clojure requires less ceremony to accomplish the same result. In Clojure, you would define person with a single line: (defstruct person :first-name :last-name) but, in Java, a class with field getters and setters would be around 20 lines of code.Examples
List (1 2 3 4 5)same as (1, 2, 3, 4, 5)
Vector [1 2 3 4 5]
Map {:a 1 :b 2 :c 3 :d 4}
Set #{lisp scheme clojure}
Simple Operations
(drop 2 [1 2 3 4 5]) -> (3 4 5)(partition 3 [1 2 3 4 5 6]) -> ((1 2) (3 4) (5 6))
(map vector [:a :b :c] [1 2 3]) -> ([:a 1] [:b 2] [:c 3])
(def m {:a 1 :b 2 :c 3}) -> #=(var user/m)
(m :b) -> 2
(keys m) -> (:a :b :c)
Assignment
Clojure is free of side effects, no matter how desirable the side effect. Your code does not modify your variables. You must capture the output in a new variable in order to retain the output of the operation. user=> (def sm (sorted-map :a 1 :b 2)) #=(var user/sm) user=> (conj sm {:c 3}) {:a 1, :b 2, :c 3} user=> sm {:a 1, :b 2} user=> (def sm2 (conj sm {:c 3 :d 4})) #=(var user/sm2) user=> sm2 {:a 1, :b 2, :c 3, :d 4}Java Interoperability
(new java.util.Date) (. Math PI)(.. System getProperties (get "java.version"))