Practical Clojure
Programming



Howard M. Lewis Ship
TWD Consulting
hlship@gmail.com
                       1   © 2010 Ho...
Agenda

• Build Tools
• Sharing Your Code
• IDE Support


                      2   © 2010 Howard M. Lewis Ship
Build Tools




              3   © 2010 Howard M. Lewis Ship
Leiningen




                                                                               “A build tool for
           ...
$ lein compile




                 lein
             (shell script)



             leiningen.jar
                       ...
6                  © 2010 Howard M. Lewis Ship




lein is a Unix shell script; self-install downloads Clojure and the Lei...
common lein
      commands
• new — create empty project
• deps — download dependencies to lib
• compile
• test
• jar
• cle...
8                  © 2010 Howard M. Lewis Ship




lein uses some Maven infrastructure; downloaded dependencies live in ~/...
.
|--   README
|--   lib
|     |-- clojure-1.1.0.jar
|     `-- clojure-contrib-1.1.0.jar
|--   project.clj
|--   src
|    ...
project.clj
(defproject com.howardlewisship/example "1.0.0-SNAPSHOT"
  :description "FIXME: write"
  :dependencies [[org.c...
Cascade
                                    .
                                    |--   lib
                              ...
(defproject com.howardlewisship.cascade/cascade-core "1.0.0-SNAPSHOT"
  :description "Simple, fast, easy web applications ...
Group Id                     Artifact Id               Version


(defproject com.howardlewisship.cascade/cascade-core "1.0...
:dependencies — Runtime Dependencies
                                             :dev-dependencies — Build/Test Dependenc...
Maven Repositories

• central — http://repo1.maven.org/maven2
• clojure — http://build.clojure.org/releases
• clojure-snap...
:omit-default-repositories true
:repositories {
  "jboss" "https://repository.jboss.org/nexus/
content/repositories/releas...
Compile all source files
                                                                            in :source-path direct...
cascade/version.clj
                                        (ns ^{:doc "Main function to display the version number of the...
:compile-path "target/classes"
:source-path "src/main/clojure"
:test-path "src/test/clojure"
:resources-path "src/main/res...
Lein Issues

• Horrible, confusing name
• Targets Maven more than Ant
• Only one command at a time
• Little bit slow to st...
Maven




                                                  21    © 2010 Howard M. Lewis Ship




http://maven.apache.org
...
Cold clean compile:
                                                                          4m 32s
                     ...
Maven Issues

• Confusing & distressing to use
• Huge, ugly XML build file
• Lots of weird downloads on first use
• Slower t...
Gradle
                                              24     © 2010 Howard M. Lewis Ship




http://gradle.org/

http://bit...
Cold clean compile:
                                                                               3m 30s
                ...
Gradle Summary
                                         • Very slick in many areas
                                       ...
Build Summary

                                        • Try Lein, hope for the best
                                     ...
Sharing Your Code




        28    © 2010 Howard M. Lewis Ship
29   © 2010 Howard M. Lewis Ship
30   © 2010 Howard M. Lewis Ship
31                 © 2010 Howard M. Lewis Ship




Why not "lein push"? the necessary Lein plugin is compiled against Cloj...
32   © 2010 Howard M. Lewis Ship
IDE Support
          33   © 2010 Howard M. Lewis Ship
Eclipse


• Counterclockwise 0.0.95.RC2
• http://code.google.com/p/counterclockwise/


                    34             ...
35   © 2010 Howard M. Lewis Ship
IntelliJ IDEA




                                          • La Clojure 0.2.267
                                         ...
37   © 2010 Howard M. Lewis Ship
NetBeans


                                                               • NetBeans 6.9
                                 ...
39   © 2010 Howard M. Lewis Ship
Emacs




  40    © 2010 Howard M. Lewis Ship
IDE Support


• Frustrating
• NetBeans feels most advanced
• AOT support limited in all


                    41          ...
Wrap Up


• Explosive growth in Clojure interest
• Tools just catching up
• Like Java in 2001?


                     42  ...
Slides

• Will be available on SlideShare
  http://www.slideshare.net/hlship


• … and rate me at SpeakerRate:
  http://sp...
© 2009 fdecomite
http://www.flickr.com/photos/fdecomite/3185386870/
                                                       ...
Upcoming SlideShare
Loading in …5
×

Practical Clojure Programming

4,289 views

Published on

Talk on Clojure infrastructure given at OSCON 2010.

Published in: Technology
0 Comments
5 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
4,289
On SlideShare
0
From Embeds
0
Number of Embeds
10
Actions
Shares
0
Downloads
0
Comments
0
Likes
5
Embeds 0
No embeds

No notes for slide

Practical Clojure Programming

  1. 1. Practical Clojure Programming Howard M. Lewis Ship TWD Consulting hlship@gmail.com 1 © 2010 Howard M. Lewis Ship
  2. 2. Agenda • Build Tools • Sharing Your Code • IDE Support 2 © 2010 Howard M. Lewis Ship
  3. 3. Build Tools 3 © 2010 Howard M. Lewis Ship
  4. 4. Leiningen “A build tool for Clojure designed to not set your hair on fire” 4 © 2010 Howard M. Lewis Ship “Leiningen Versus the Ants” is a short story from 1938 about a plantation owner fighting a battle against 20 square miles of Army Ants. http://en.wikipedia.org/wiki/Leiningen_Versus_the_Ants
  5. 5. $ lein compile lein (shell script) leiningen.jar project.clj (Clojure) Maven Ant Ant tasks Clojure Tasks Copying, AOT Dependency packaging Compilation Resolution 5 © 2010 Howard M. Lewis Ship
  6. 6. 6 © 2010 Howard M. Lewis Ship lein is a Unix shell script; self-install downloads Clojure and the Leiningen JARs from http://github.com/downloads/technomancy/ leiningen I had previously added ~/bin to my Unix $PATH Note: Most of this presentation was done with an alpha version of Leiningen 1.2 (I may need to update the movie to reflect this properly)
  7. 7. common lein commands • new — create empty project • deps — download dependencies to lib • compile • test • jar • clean 7 © 2010 Howard M. Lewis Ship
  8. 8. 8 © 2010 Howard M. Lewis Ship lein uses some Maven infrastructure; downloaded dependencies live in ~/.m2/repository (the download is needed just once)
  9. 9. . |-- README |-- lib | |-- clojure-1.1.0.jar | `-- clojure-contrib-1.1.0.jar |-- project.clj |-- src | `-- com | `-- howardlewisship | `-- example | `-- core.clj `-- test `-- com `-- howardlewisship `-- example `-- core_test.clj 9 © 2010 Howard M. Lewis Ship
  10. 10. project.clj (defproject com.howardlewisship/example "1.0.0-SNAPSHOT" :description "FIXME: write" :dependencies [[org.clojure/clojure "1.1.0"] [org.clojure/clojure-contrib "1.1.0"]]) 10 © 2010 Howard M. Lewis Ship
  11. 11. Cascade . |-- lib | `-- dev |-- project.clj |-- src | |-- main | | |-- clojure | | `-- resources | `-- test | |-- clojure | |-- resources | `-- webapp `-- target `-- classes 11 © 2010 Howard M. Lewis Ship http://hlship.github.com/cascade/
  12. 12. (defproject com.howardlewisship.cascade/cascade-core "1.0.0-SNAPSHOT" :description "Simple, fast, easy web applications in idiomatic Clojure" :url "http://github.com/hlship/cascade/" :dependencies [[org.clojure/clojure "1.1.0"] [org.clojure/clojure-contrib "1.1.0"] [org.slf4j/slf4j-api "1.5.2"] [org.slf4j/slf4j-log4j12 "1.5.2"] [log4j/log4j "1.2.14"]] :dev-dependencies [[org.eclipse.jetty/jetty-server "7.0.0.RC4"] [org.eclipse.jetty/jetty-servlet "7.0.0.RC4"] [org.easymock/easymock "2.5.1"] [org.seleniumhq.selenium.server/selenium-server "1.0.3" :classifier "standalone"]] :aot [cascade.filter] :warn-on-reflection true :main cascade.version :source-path "src/main/clojure" :test-path "src/test/clojure" :resources-path "src/main/resources" :test-resources-path "src/test/resources" :compile-path "target/classes" :jar-dir "target") 12 © 2010 Howard M. Lewis Ship
  13. 13. Group Id Artifact Id Version (defproject com.howardlewisship.cascade/cascade-core "1.0.0-SNAPSHOT" :description "Simple, fast, easy web applications in idiomatic Clojure" :url "http://github.com/hlship/cascade/" 13 © 2010 Howard M. Lewis Ship
  14. 14. :dependencies — Runtime Dependencies :dev-dependencies — Build/Test Dependencies Group Id [org.clojure/clojure-contrib "1.1.0"] Artifact Id Version [org.seleniumhq.selenium.server/selenium-server "1.0.3" :classifier "standalone"] [log4j "1.2.15" :exclusions [javax.mail/mail javax.jms/jms]] 14 © 2010 Howard M. Lewis Ship :dependencies will become transitive dependencies of other projects that depend on this one (unless excluded) :dev-dependencies are just used for testing, or as a source of lein plugins
  15. 15. Maven Repositories • central — http://repo1.maven.org/maven2 • clojure — http://build.clojure.org/releases • clojure-snapshots — http:// build.clojure.org/snapshots • clojars — http://clojars.org/repo/ 15 © 2010 Howard M. Lewis Ship
  16. 16. :omit-default-repositories true :repositories { "jboss" "https://repository.jboss.org/nexus/ content/repositories/releases/" } Additional repositories: id and URL 16 © 2010 Howard M. Lewis Ship
  17. 17. Compile all source files in :source-path directory :aot — vector of namespaces to AOT compile, or :all :namespaces — deprecated alternative to :aot :warn-on-reflection — Compiler warning when Java method invocation requires reflection :main — Namespace containing a main function, becomes Main-Class Manifest entry 17 © 2010 Howard M. Lewis Ship Reflection is needed when invoking Java methods on objects without type hints (on the receiving object, and for the method parameters). Clojure just knows its an object, but hasn't enough type information to determine at build time what the particular method to invoke will be. This is a big performance hit.
  18. 18. cascade/version.clj (ns ^{:doc "Main function to display the version number of the framework"} cascade.version (:use [cascade config]) (:gen-class)) Command line args (defn -main [& args] (println (format "Cascade version %s" (read-config :cascade-version)))) $ lein uberjar ... Created target/cascade-core-1.0.0-SNAPSHOT-standalone.jar ~/clojure-workspace/cascade $ java -jar target/cascade-core-1.0.0-SNAPSHOT-standalone.jar Cascade version 1.0.0-SNAPSHOT ~/clojure-workspace/cascade $ 18 © 2010 Howard M. Lewis Ship At time of writing, uberjar would not work except with the default :jar-dir of . (I slightly doctored the text to show what it will look like once fixed).
  19. 19. :compile-path "target/classes" :source-path "src/main/clojure" :test-path "src/test/clojure" :resources-path "src/main/resources" :test-resources-path "src/test/resources" :compile-path "target/classes" :jar-dir "target" Where to put Where to create compiled namespaces constructed JARs :compile-path classes :source-path src :test-path test :library-path lib :resources-path resources :test-resources-path test-resources :jar-dir . 19 © 2010 Howard M. Lewis Ship
  20. 20. Lein Issues • Horrible, confusing name • Targets Maven more than Ant • Only one command at a time • Little bit slow to start • Documentation is terrible 20 © 2010 Howard M. Lewis Ship
  21. 21. Maven 21 © 2010 Howard M. Lewis Ship http://maven.apache.org http://github.com/talios/clojure-maven-plugin
  22. 22. Cold clean compile: 4m 32s 12 MB (392 files) Clean compile: 40s 22 © 2010 Howard M. Lewis Ship pom.xml available at http://github.com/hlship/cascade/blob/maven-build/pom.xml
  23. 23. Maven Issues • Confusing & distressing to use • Huge, ugly XML build file • Lots of weird downloads on first use • Slower than Lein • Wouldn't compile cascade.filter Why? 23 © 2010 Howard M. Lewis Ship
  24. 24. Gradle 24 © 2010 Howard M. Lewis Ship http://gradle.org/ http://bitbucket.org/kotarak/clojuresque/
  25. 25. Cold clean compile: 3m 30s 27 MB (129 files) Clean compile: 40s 25 © 2010 Howard M. Lewis Ship build.gradle available at http://github.com/hlship/cascade/blob/gradle-build/build.gradle
  26. 26. Gradle Summary • Very slick in many areas • Need to learn some Groovy syntax • Not as focused/succinct as Lein • Clojuresque plugin very immature • Better documentation, still occasionally patchy • No real docs for Clojuresque 26 © 2010 Howard M. Lewis Ship CLI has many useful features such as clean quick way to display dependencies; it's also cleaner about reporting downloads from remote repositories. It's a more fully featured build system, but it's also a lot to take in.
  27. 27. Build Summary • Try Lein, hope for the best • Keep tabs on Gradle & Clojuresque • Avoid Maven • AOT Compilation of libraries a problem 27 © 2010 Howard M. Lewis Ship A irritation now is that AOT compilation (which can be necessary in many cases) can cause unwanted compilation of namespaces from libraries. See http://www.assembla.com/spaces/clojure/tickets/322
  28. 28. Sharing Your Code 28 © 2010 Howard M. Lewis Ship
  29. 29. 29 © 2010 Howard M. Lewis Ship
  30. 30. 30 © 2010 Howard M. Lewis Ship
  31. 31. 31 © 2010 Howard M. Lewis Ship Why not "lein push"? the necessary Lein plugin is compiled against Clojure 1.1 and Cascade is tracking against 1.2. Fall down, go boom. This is usually a problem with code that requires AOT, which it the case for cascade.filter. Still, it's very unfortunate. I use SSHKeyChain.app to help manage my SSH sessions; otherwise I'd be prompted for my secret key when I execute the scp command.
  32. 32. 32 © 2010 Howard M. Lewis Ship
  33. 33. IDE Support 33 © 2010 Howard M. Lewis Ship
  34. 34. Eclipse • Counterclockwise 0.0.95.RC2 • http://code.google.com/p/counterclockwise/ 34 © 2010 Howard M. Lewis Ship
  35. 35. 35 © 2010 Howard M. Lewis Ship
  36. 36. IntelliJ IDEA • La Clojure 0.2.267 • Built-in to community edition 36 © 2010 Howard M. Lewis Ship La Clojure was one of the first IDE plugins available
  37. 37. 37 © 2010 Howard M. Lewis Ship
  38. 38. NetBeans • NetBeans 6.9 • Enclojure 1.2.1 38 © 2010 Howard M. Lewis Ship Installation details at http://www.assembla.com/wiki/show/clojure/Getting_Started_with_Netbeans_and_Enclojure
  39. 39. 39 © 2010 Howard M. Lewis Ship
  40. 40. Emacs 40 © 2010 Howard M. Lewis Ship
  41. 41. IDE Support • Frustrating • NetBeans feels most advanced • AOT support limited in all 41 © 2010 Howard M. Lewis Ship
  42. 42. Wrap Up • Explosive growth in Clojure interest • Tools just catching up • Like Java in 2001? 42 © 2010 Howard M. Lewis Ship
  43. 43. Slides • Will be available on SlideShare http://www.slideshare.net/hlship • … and rate me at SpeakerRate: http://speakerrate.com/speakers/3749- howard-m-lewis-ship 43 © 2010 Howard M. Lewis Ship
  44. 44. © 2009 fdecomite http://www.flickr.com/photos/fdecomite/3185386870/ © 2008 Hallvard E http://www.flickr.com/photos/eldholm/2354982554/ © 2005 Steve Jurvetson http://www.flickr.com/photos/jurvetson/70704300/ © 2006 Chris Walton http://www.flickr.com/photos/philocrites/245011706/ © 2007 Howard Gees http://www.flickr.com/photos/cyberslayer/952153409/ © 2007 pickinjim2006 http://www.flickr.com/photos/81838529@N00/525129498/ © 2005 Jean-Philippe Daigle http://www.flickr.com/photos/jpdaigle/59942231/ © 2007 QQ Li http://www.flickr.com/photos/ozyman/443545349/ © 2008 MadAboutCows http://www.flickr.com/photos/madaboutcows/2933510443/ © 2008 Martin Junius http://www.flickr.com/photos/m-j-s/2724756177/ 44 © 2010 Howard M. Lewis Ship

×