SlideShare a Scribd company logo
Practical Clojure
Programming



Howard M. Lewis Ship
TWD Consulting
hlship@gmail.com
                       1   © 2010 Howard M. Lewis Ship
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
                                                                               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
$ 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                  © 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)
common lein
      commands
• new — create empty project
• deps — download dependencies to lib
• compile
• test
• jar
• clean
                    7              © 2010 Howard M. Lewis Ship
8                  © 2010 Howard M. Lewis Ship




lein uses some Maven infrastructure; downloaded dependencies live in ~/.m2/repository (the download is needed just once)
.
|--   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
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
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/
(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
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
: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
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
: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
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.
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).
: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
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
Maven




                                                  21    © 2010 Howard M. Lewis Ship




http://maven.apache.org

http://github.com/talios/clojure-maven-plugin
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
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
Gradle
                                              24     © 2010 Howard M. Lewis Ship




http://gradle.org/

http://bitbucket.org/kotarak/clojuresque/
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
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.
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
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 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   © 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               © 2010 Howard M. Lewis Ship
35   © 2010 Howard M. Lewis Ship
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   © 2010 Howard M. Lewis Ship
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   © 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           © 2010 Howard M. Lewis Ship
Wrap Up


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


                     42                  © 2010 Howard M. Lewis Ship
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
© 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

More Related Content

PDF
Liferay maven sdk
PDF
Использование maven для сборки больших модульных c++ проектов на примере Odin...
PPTX
How to add a new hypervisor to CloudStack - Lessons learned from Hyper-V effort
PPTX
Supporting Hyper-V 3.0 on Apache CloudStack
PDF
Security Goodness with Ruby on Rails
PDF
Groovy, Transforming Language
PDF
Ruby on Rails 101 - Presentation Slides for a Five Day Introductory Course
PPT
EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js
Liferay maven sdk
Использование maven для сборки больших модульных c++ проектов на примере Odin...
How to add a new hypervisor to CloudStack - Lessons learned from Hyper-V effort
Supporting Hyper-V 3.0 on Apache CloudStack
Security Goodness with Ruby on Rails
Groovy, Transforming Language
Ruby on Rails 101 - Presentation Slides for a Five Day Introductory Course
EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

What's hot (20)

PPT
Migrating PriceChirp to Rails 3.0: The Pain Points
PDF
Dynamic Languages & Web Frameworks in GlassFish
PDF
Saint2012 mod process security
PDF
Cloud Foundry Open Tour China
PDF
O que há de novo no Rails 3
PDF
Cloud Foundry Open Tour China (english)
PPTX
Apache CloudStack's Plugin Model: Balancing the Cathedral with a Bazaar
KEY
Практики применения JRuby
PPTX
17 camera, media, and audio in windows phone 8.1
PDF
Buildr In Action @devoxx france 2012
PDF
Debugging on rails
PDF
QEWD Update
KEY
Jruby synergy-of-ruby-and-java
PDF
Groovy Power Features
PDF
Docker for (Java) Developers
PDF
Gradle - Build system evolved
PDF
Build an autoversioning filesystem with Apache2
PDF
Ror Seminar With agilebd.org on 23 Jan09
PDF
JRuby on Rails Deployment: What They Didn't Tell You
KEY
Ruby on Rails Training - Module 1
Migrating PriceChirp to Rails 3.0: The Pain Points
Dynamic Languages & Web Frameworks in GlassFish
Saint2012 mod process security
Cloud Foundry Open Tour China
O que há de novo no Rails 3
Cloud Foundry Open Tour China (english)
Apache CloudStack's Plugin Model: Balancing the Cathedral with a Bazaar
Практики применения JRuby
17 camera, media, and audio in windows phone 8.1
Buildr In Action @devoxx france 2012
Debugging on rails
QEWD Update
Jruby synergy-of-ruby-and-java
Groovy Power Features
Docker for (Java) Developers
Gradle - Build system evolved
Build an autoversioning filesystem with Apache2
Ror Seminar With agilebd.org on 23 Jan09
JRuby on Rails Deployment: What They Didn't Tell You
Ruby on Rails Training - Module 1
Ad

Viewers also liked (14)

PPTX
Prevention Sciences Program Present & Future
PDF
Salisbury Pro-Wear Arc Flash Protection Premium Overpants 8 - 20cal/cm²
PDF
Certificates_Bakhtiar Saffuan 7
PDF
EDV-Unterstützung in der Instandhaltung_TA01-12-A
PDF
PDF
ADOPTION OF NEURAL NETWORK IN FORECASTING THE TRENDS OF STOCK MARKET
PDF
WINN 5 jaar inspireren doorzetten en doen (brochure)
PDF
HUNTER, Linda - SFA certificate
PDF
2016 Urbanistica, per iniziare! On the begin of a talk on planning looking a...
PPTX
Translational Fellowships in Public Mental Health Services
PDF
WSJ-Compliance Risks What You Don’t Contain Can Hurt You - Deloitte Risk (1)
PDF
Grade 8 chemistry vocabulary list
PDF
Salisbury Pro-Wear HRC2 Arc Flash Clothing & Protection Kit 8 cal/cm² ATPV
PPTX
Prevention Sciences Program Present & Future
Salisbury Pro-Wear Arc Flash Protection Premium Overpants 8 - 20cal/cm²
Certificates_Bakhtiar Saffuan 7
EDV-Unterstützung in der Instandhaltung_TA01-12-A
ADOPTION OF NEURAL NETWORK IN FORECASTING THE TRENDS OF STOCK MARKET
WINN 5 jaar inspireren doorzetten en doen (brochure)
HUNTER, Linda - SFA certificate
2016 Urbanistica, per iniziare! On the begin of a talk on planning looking a...
Translational Fellowships in Public Mental Health Services
WSJ-Compliance Risks What You Don’t Contain Can Hurt You - Deloitte Risk (1)
Grade 8 chemistry vocabulary list
Salisbury Pro-Wear HRC2 Arc Flash Clothing & Protection Kit 8 cal/cm² ATPV
Ad

Similar to Practical Clojure Programming (20)

PDF
Leiningen 2 - Humane build management for Clojure
PPTX
Apache Maven
ODP
Leiningen2 - humane build management for clojure
PDF
Gradleintroduction 111010130329-phpapp01
PDF
Gradle Introduction
PDF
Gradle talk, Javarsovia 2010
PDF
Simple Build Tool
PDF
Apache Maven - eXo TN presentation
PDF
Geneva Jug (30th March, 2010) - Maven
PDF
Apache Maven at GenevaJUG by Arnaud Héritier
PDF
Hands On with Maven
PDF
Gradle - time for a new build
PDF
Lausanne Jug (08th April, 2010) - Maven
PDF
Alpes Jug (29th March, 2010) - Apache Maven
PDF
Riviera JUG (20th April, 2010) - Maven
PDF
Clojure and Modularity
PDF
Ant, Maven and Jenkins
PDF
Gradle build tool that rocks with DSL JavaOne India 4th May 2012
PDF
Intro to J Ruby
PDF
Lorraine JUG (1st June, 2010) - Maven
Leiningen 2 - Humane build management for Clojure
Apache Maven
Leiningen2 - humane build management for clojure
Gradleintroduction 111010130329-phpapp01
Gradle Introduction
Gradle talk, Javarsovia 2010
Simple Build Tool
Apache Maven - eXo TN presentation
Geneva Jug (30th March, 2010) - Maven
Apache Maven at GenevaJUG by Arnaud Héritier
Hands On with Maven
Gradle - time for a new build
Lausanne Jug (08th April, 2010) - Maven
Alpes Jug (29th March, 2010) - Apache Maven
Riviera JUG (20th April, 2010) - Maven
Clojure and Modularity
Ant, Maven and Jenkins
Gradle build tool that rocks with DSL JavaOne India 4th May 2012
Intro to J Ruby
Lorraine JUG (1st June, 2010) - Maven

More from Howard Lewis Ship (17)

PDF
Testing Web Applications with GEB
PDF
Spock: A Highly Logical Way To Test
PDF
Backbone.js: Run your Application Inside The Browser
PDF
Modern Application Foundations: Underscore and Twitter Bootstrap
KEY
Have Your Cake and Eat It Too: Meta-Programming Techniques for Java
PDF
Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)
PDF
Arduino: Open Source Hardware Hacking from the Software Nerd Perspective
PDF
Clojure: Towards The Essence of Programming
PDF
Codemash-Clojure.pdf
PDF
Codemash-Tapestry.pdf
PDF
Tapestry 5: Java Power, Scripting Ease
PDF
Brew up a Rich Web Application with Cappuccino
PDF
Clojure Deep Dive
PDF
Clojure: Functional Concurrency for the JVM (presented at OSCON)
PDF
PDF
Tapestry: State of the Union
ZIP
Clojure: Functional Concurrency for the JVM (presented at Open Source Bridge)
Testing Web Applications with GEB
Spock: A Highly Logical Way To Test
Backbone.js: Run your Application Inside The Browser
Modern Application Foundations: Underscore and Twitter Bootstrap
Have Your Cake and Eat It Too: Meta-Programming Techniques for Java
Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)
Arduino: Open Source Hardware Hacking from the Software Nerd Perspective
Clojure: Towards The Essence of Programming
Codemash-Clojure.pdf
Codemash-Tapestry.pdf
Tapestry 5: Java Power, Scripting Ease
Brew up a Rich Web Application with Cappuccino
Clojure Deep Dive
Clojure: Functional Concurrency for the JVM (presented at OSCON)
Tapestry: State of the Union
Clojure: Functional Concurrency for the JVM (presented at Open Source Bridge)

Recently uploaded (20)

PDF
Chapter 3 Spatial Domain Image Processing.pdf
PPT
Teaching material agriculture food technology
PDF
HCSP-Presales-Campus Network Planning and Design V1.0 Training Material-Witho...
PDF
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
PDF
Modernizing your data center with Dell and AMD
PDF
Review of recent advances in non-invasive hemoglobin estimation
PDF
CIFDAQ's Market Insight: SEC Turns Pro Crypto
PDF
Dropbox Q2 2025 Financial Results & Investor Presentation
PDF
Advanced IT Governance
PDF
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
PDF
Advanced methodologies resolving dimensionality complications for autism neur...
PDF
Sensors and Actuators in IoT Systems using pdf
PPTX
Understanding_Digital_Forensics_Presentation.pptx
PPTX
breach-and-attack-simulation-cybersecurity-india-chennai-defenderrabbit-2025....
PPTX
MYSQL Presentation for SQL database connectivity
PDF
How Onsite IT Support Drives Business Efficiency, Security, and Growth.pdf
PDF
Spectral efficient network and resource selection model in 5G networks
PDF
GamePlan Trading System Review: Professional Trader's Honest Take
PDF
Reach Out and Touch Someone: Haptics and Empathic Computing
PPTX
Cloud computing and distributed systems.
Chapter 3 Spatial Domain Image Processing.pdf
Teaching material agriculture food technology
HCSP-Presales-Campus Network Planning and Design V1.0 Training Material-Witho...
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
Modernizing your data center with Dell and AMD
Review of recent advances in non-invasive hemoglobin estimation
CIFDAQ's Market Insight: SEC Turns Pro Crypto
Dropbox Q2 2025 Financial Results & Investor Presentation
Advanced IT Governance
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
Advanced methodologies resolving dimensionality complications for autism neur...
Sensors and Actuators in IoT Systems using pdf
Understanding_Digital_Forensics_Presentation.pptx
breach-and-attack-simulation-cybersecurity-india-chennai-defenderrabbit-2025....
MYSQL Presentation for SQL database connectivity
How Onsite IT Support Drives Business Efficiency, Security, and Growth.pdf
Spectral efficient network and resource selection model in 5G networks
GamePlan Trading System Review: Professional Trader's Honest Take
Reach Out and Touch Someone: Haptics and Empathic Computing
Cloud computing and distributed systems.

Practical Clojure Programming

  • 1. Practical Clojure Programming Howard M. Lewis Ship TWD Consulting [email protected] 1 © 2010 Howard M. Lewis Ship
  • 2. Agenda • Build Tools • Sharing Your Code • IDE Support 2 © 2010 Howard M. Lewis Ship
  • 3. Build Tools 3 © 2010 Howard M. Lewis Ship
  • 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. $ 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 © 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. common lein commands • new — create empty project • deps — download dependencies to lib • compile • test • jar • clean 7 © 2010 Howard M. Lewis Ship
  • 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. . |-- 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. 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. 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. (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. 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. :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. 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. :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. 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. 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. :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. 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. Maven 21 © 2010 Howard M. Lewis Ship http://maven.apache.org http://github.com/talios/clojure-maven-plugin
  • 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. 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. Gradle 24 © 2010 Howard M. Lewis Ship http://gradle.org/ http://bitbucket.org/kotarak/clojuresque/
  • 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. 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. 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. Sharing Your Code 28 © 2010 Howard M. Lewis Ship
  • 29. 29 © 2010 Howard M. Lewis Ship
  • 30. 30 © 2010 Howard M. Lewis Ship
  • 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 © 2010 Howard M. Lewis Ship
  • 33. IDE Support 33 © 2010 Howard M. Lewis Ship
  • 34. Eclipse • Counterclockwise 0.0.95.RC2 • http://code.google.com/p/counterclockwise/ 34 © 2010 Howard M. Lewis Ship
  • 35. 35 © 2010 Howard M. Lewis Ship
  • 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 © 2010 Howard M. Lewis Ship
  • 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 © 2010 Howard M. Lewis Ship
  • 40. Emacs 40 © 2010 Howard M. Lewis Ship
  • 41. IDE Support • Frustrating • NetBeans feels most advanced • AOT support limited in all 41 © 2010 Howard M. Lewis Ship
  • 42. Wrap Up • Explosive growth in Clojure interest • Tools just catching up • Like Java in 2001? 42 © 2010 Howard M. Lewis Ship
  • 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. © 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