SlideShare una empresa de Scribd logo
1 de 44
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

Más contenido relacionado

La actualidad más candente

Migrating PriceChirp to Rails 3.0: The Pain Points
Migrating PriceChirp to Rails 3.0: The Pain PointsMigrating PriceChirp to Rails 3.0: The Pain Points
Migrating PriceChirp to Rails 3.0: The Pain PointsSteven Evatt
 
Dynamic Languages & Web Frameworks in GlassFish
Dynamic Languages & Web Frameworks in GlassFishDynamic Languages & Web Frameworks in GlassFish
Dynamic Languages & Web Frameworks in GlassFishIndicThreads
 
Saint2012 mod process security
Saint2012 mod process securitySaint2012 mod process security
Saint2012 mod process securityRyosuke MATSUMOTO
 
Cloud Foundry Open Tour China
Cloud Foundry Open Tour ChinaCloud Foundry Open Tour China
Cloud Foundry Open Tour Chinamarklucovsky
 
O que há de novo no Rails 3
O que há de novo no Rails 3O que há de novo no Rails 3
O que há de novo no Rails 3Hugo Baraúna
 
Cloud Foundry Open Tour China (english)
Cloud Foundry Open Tour China (english)Cloud Foundry Open Tour China (english)
Cloud Foundry Open Tour China (english)marklucovsky
 
Apache CloudStack's Plugin Model: Balancing the Cathedral with a Bazaar
Apache CloudStack's Plugin Model:Balancing the Cathedral with a BazaarApache CloudStack's Plugin Model:Balancing the Cathedral with a Bazaar
Apache CloudStack's Plugin Model: Balancing the Cathedral with a BazaarDonal Lafferty
 
Практики применения JRuby
Практики применения JRubyПрактики применения JRuby
Практики применения JRuby.toster
 
17 camera, media, and audio in windows phone 8.1
17   camera, media, and audio in windows phone 8.117   camera, media, and audio in windows phone 8.1
17 camera, media, and audio in windows phone 8.1WindowsPhoneRocks
 
Buildr In Action @devoxx france 2012
Buildr In Action @devoxx france 2012Buildr In Action @devoxx france 2012
Buildr In Action @devoxx france 2012alexismidon
 
Jruby synergy-of-ruby-and-java
Jruby synergy-of-ruby-and-javaJruby synergy-of-ruby-and-java
Jruby synergy-of-ruby-and-javaKeith Bennett
 
Groovy Power Features
Groovy Power FeaturesGroovy Power Features
Groovy Power FeaturesPaul King
 
Docker for (Java) Developers
Docker for (Java) DevelopersDocker for (Java) Developers
Docker for (Java) DevelopersRafael Benevides
 
Gradle - Build system evolved
Gradle - Build system evolvedGradle - Build system evolved
Gradle - Build system evolvedBhagwat Kumar
 
Build an autoversioning filesystem with Apache2
Build an autoversioning filesystem with Apache2Build an autoversioning filesystem with Apache2
Build an autoversioning filesystem with Apache2Javier Arturo Rodríguez
 
Ror Seminar With agilebd.org on 23 Jan09
Ror Seminar With agilebd.org on 23 Jan09Ror Seminar With agilebd.org on 23 Jan09
Ror Seminar With agilebd.org on 23 Jan09Shaer Hassan
 
JRuby on Rails Deployment: What They Didn't Tell You
JRuby on Rails Deployment: What They Didn't Tell YouJRuby on Rails Deployment: What They Didn't Tell You
JRuby on Rails Deployment: What They Didn't Tell Youelliando dias
 
Ruby on Rails Training - Module 1
Ruby on Rails Training - Module 1Ruby on Rails Training - Module 1
Ruby on Rails Training - Module 1Mark Menard
 

La actualidad más candente (20)

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

Destacado

Prevention Sciences Program Present & Future
Prevention Sciences Program Present & FuturePrevention Sciences Program Present & Future
Prevention Sciences Program Present & FutureHopkinsCFAR
 
Salisbury Pro-Wear Arc Flash Protection Premium Overpants 8 - 20cal/cm²
Salisbury Pro-Wear Arc Flash Protection Premium Overpants 8 - 20cal/cm²Salisbury Pro-Wear Arc Flash Protection Premium Overpants 8 - 20cal/cm²
Salisbury Pro-Wear Arc Flash Protection Premium Overpants 8 - 20cal/cm²Thorne & Derrick International
 
ADOPTION OF NEURAL NETWORK IN FORECASTING THE TRENDS OF STOCK MARKET
ADOPTION OF NEURAL NETWORK IN FORECASTING THE TRENDS OF STOCK MARKETADOPTION OF NEURAL NETWORK IN FORECASTING THE TRENDS OF STOCK MARKET
ADOPTION OF NEURAL NETWORK IN FORECASTING THE TRENDS OF STOCK MARKETijcoa
 
WINN 5 jaar inspireren doorzetten en doen (brochure)
WINN 5 jaar inspireren doorzetten en doen (brochure)WINN 5 jaar inspireren doorzetten en doen (brochure)
WINN 5 jaar inspireren doorzetten en doen (brochure)Bert Polak ∴
 
HUNTER, Linda - SFA certificate
HUNTER, Linda - SFA certificateHUNTER, Linda - SFA certificate
HUNTER, Linda - SFA certificateLinda Hunter
 
2016 Urbanistica, per iniziare! On the begin of a talk on planning looking a...
 2016 Urbanistica, per iniziare! On the begin of a talk on planning looking a... 2016 Urbanistica, per iniziare! On the begin of a talk on planning looking a...
2016 Urbanistica, per iniziare! On the begin of a talk on planning looking a...Luca Marescotti
 
Translational Fellowships in Public Mental Health Services
Translational Fellowships in Public Mental Health ServicesTranslational Fellowships in Public Mental Health Services
Translational Fellowships in Public Mental Health ServicesUCLA CTSI
 
WSJ-Compliance Risks What You Don’t Contain Can Hurt You - Deloitte Risk (1)
WSJ-Compliance Risks What You Don’t Contain Can Hurt You - Deloitte Risk (1)WSJ-Compliance Risks What You Don’t Contain Can Hurt You - Deloitte Risk (1)
WSJ-Compliance Risks What You Don’t Contain Can Hurt You - Deloitte Risk (1)Keith Darcy
 
Grade 8 chemistry vocabulary list
Grade 8 chemistry vocabulary listGrade 8 chemistry vocabulary list
Grade 8 chemistry vocabulary listBrad Kremer
 
Salisbury Pro-Wear HRC2 Arc Flash Clothing & Protection Kit 8 cal/cm² ATPV
Salisbury Pro-Wear HRC2 Arc Flash Clothing & Protection Kit 8 cal/cm² ATPV Salisbury Pro-Wear HRC2 Arc Flash Clothing & Protection Kit 8 cal/cm² ATPV
Salisbury Pro-Wear HRC2 Arc Flash Clothing & Protection Kit 8 cal/cm² ATPV Thorne & Derrick International
 

Destacado (15)

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

Similar a Practical Clojure Programming

Extending Build to the Client: A Maven User's Guide to Grunt.js
Extending Build to the Client: A Maven User's Guide to Grunt.jsExtending Build to the Client: A Maven User's Guide to Grunt.js
Extending Build to the Client: A Maven User's Guide to Grunt.jsPetr Jiricka
 
Vagrant or docker for java dev environment
Vagrant or docker for java dev environmentVagrant or docker for java dev environment
Vagrant or docker for java dev environmentOrest Ivasiv
 
Note - Apache Maven Intro
Note - Apache Maven IntroNote - Apache Maven Intro
Note - Apache Maven Introboyw165
 
JSUG - Maven by Michael Greifeneder
JSUG - Maven by Michael GreifenederJSUG - Maven by Michael Greifeneder
JSUG - Maven by Michael GreifenederChristoph Pickl
 
Linux containers and docker
Linux containers and dockerLinux containers and docker
Linux containers and dockerFabio Fumarola
 
Docker module 1
Docker module 1Docker module 1
Docker module 1Liang Bo
 
Webinar: Creating an Effective Docker Build Pipeline for Java Apps
Webinar: Creating an Effective Docker Build Pipeline for Java AppsWebinar: Creating an Effective Docker Build Pipeline for Java Apps
Webinar: Creating an Effective Docker Build Pipeline for Java AppsCodefresh
 
Maven introduction in Mule
Maven introduction in MuleMaven introduction in Mule
Maven introduction in MuleShahid Shaik
 
Brew up a Rich Web Application with Cappuccino
Brew up a Rich Web Application with CappuccinoBrew up a Rich Web Application with Cappuccino
Brew up a Rich Web Application with CappuccinoHoward Lewis Ship
 
Java in a world of containers
Java in a world of containersJava in a world of containers
Java in a world of containersDocker, Inc.
 
Java in a World of Containers - DockerCon 2018
Java in a World of Containers - DockerCon 2018Java in a World of Containers - DockerCon 2018
Java in a World of Containers - DockerCon 2018Arun Gupta
 
Gradle talk, Javarsovia 2010
Gradle talk, Javarsovia 2010Gradle talk, Javarsovia 2010
Gradle talk, Javarsovia 2010Tomek Kaczanowski
 
Austin - Container Days - Docker 101
Austin - Container Days - Docker 101Austin - Container Days - Docker 101
Austin - Container Days - Docker 101Bill Maxwell
 
Ruby on Rails All Hands Meeting
Ruby on Rails All Hands MeetingRuby on Rails All Hands Meeting
Ruby on Rails All Hands MeetingDan Davis
 
Developing Liferay Plugins with Maven
Developing Liferay Plugins with MavenDeveloping Liferay Plugins with Maven
Developing Liferay Plugins with MavenMika Koivisto
 
Lightning talk: 12 Factor Containers
Lightning talk: 12 Factor ContainersLightning talk: 12 Factor Containers
Lightning talk: 12 Factor ContainersMukhtar Haji
 

Similar a Practical Clojure Programming (20)

Extending Build to the Client: A Maven User's Guide to Grunt.js
Extending Build to the Client: A Maven User's Guide to Grunt.jsExtending Build to the Client: A Maven User's Guide to Grunt.js
Extending Build to the Client: A Maven User's Guide to Grunt.js
 
Vagrant or docker for java dev environment
Vagrant or docker for java dev environmentVagrant or docker for java dev environment
Vagrant or docker for java dev environment
 
Note - Apache Maven Intro
Note - Apache Maven IntroNote - Apache Maven Intro
Note - Apache Maven Intro
 
JSUG - Maven by Michael Greifeneder
JSUG - Maven by Michael GreifenederJSUG - Maven by Michael Greifeneder
JSUG - Maven by Michael Greifeneder
 
Linux containers and docker
Linux containers and dockerLinux containers and docker
Linux containers and docker
 
Docker module 1
Docker module 1Docker module 1
Docker module 1
 
Webinar: Creating an Effective Docker Build Pipeline for Java Apps
Webinar: Creating an Effective Docker Build Pipeline for Java AppsWebinar: Creating an Effective Docker Build Pipeline for Java Apps
Webinar: Creating an Effective Docker Build Pipeline for Java Apps
 
Maven introduction in Mule
Maven introduction in MuleMaven introduction in Mule
Maven introduction in Mule
 
Brew up a Rich Web Application with Cappuccino
Brew up a Rich Web Application with CappuccinoBrew up a Rich Web Application with Cappuccino
Brew up a Rich Web Application with Cappuccino
 
Java in a world of containers
Java in a world of containersJava in a world of containers
Java in a world of containers
 
Java in a World of Containers - DockerCon 2018
Java in a World of Containers - DockerCon 2018Java in a World of Containers - DockerCon 2018
Java in a World of Containers - DockerCon 2018
 
Gradle talk, Javarsovia 2010
Gradle talk, Javarsovia 2010Gradle talk, Javarsovia 2010
Gradle talk, Javarsovia 2010
 
Austin - Container Days - Docker 101
Austin - Container Days - Docker 101Austin - Container Days - Docker 101
Austin - Container Days - Docker 101
 
Maven in Mule
Maven in MuleMaven in Mule
Maven in Mule
 
Ruby on Rails All Hands Meeting
Ruby on Rails All Hands MeetingRuby on Rails All Hands Meeting
Ruby on Rails All Hands Meeting
 
Maven
MavenMaven
Maven
 
Developing Liferay Plugins with Maven
Developing Liferay Plugins with MavenDeveloping Liferay Plugins with Maven
Developing Liferay Plugins with Maven
 
Lightning talk: 12 Factor Containers
Lightning talk: 12 Factor ContainersLightning talk: 12 Factor Containers
Lightning talk: 12 Factor Containers
 
Apache Maven for AT/QC
Apache Maven for AT/QCApache Maven for AT/QC
Apache Maven for AT/QC
 
Apache Maven
Apache MavenApache Maven
Apache Maven
 

Más de Howard Lewis Ship

Testing Web Applications with GEB
Testing Web Applications with GEBTesting Web Applications with GEB
Testing Web Applications with GEBHoward Lewis Ship
 
Spock: A Highly Logical Way To Test
Spock: A Highly Logical Way To TestSpock: A Highly Logical Way To Test
Spock: A Highly Logical Way To TestHoward Lewis Ship
 
Backbone.js: Run your Application Inside The Browser
Backbone.js: Run your Application Inside The BrowserBackbone.js: Run your Application Inside The Browser
Backbone.js: Run your Application Inside The BrowserHoward Lewis Ship
 
Modern Application Foundations: Underscore and Twitter Bootstrap
Modern Application Foundations: Underscore and Twitter BootstrapModern Application Foundations: Underscore and Twitter Bootstrap
Modern Application Foundations: Underscore and Twitter BootstrapHoward Lewis Ship
 
Have Your Cake and Eat It Too: Meta-Programming Techniques for Java
Have Your Cake and Eat It Too: Meta-Programming Techniques for JavaHave Your Cake and Eat It Too: Meta-Programming Techniques for Java
Have Your Cake and Eat It Too: Meta-Programming Techniques for JavaHoward Lewis Ship
 
Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)
Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)
Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)Howard Lewis Ship
 
Arduino: Open Source Hardware Hacking from the Software Nerd Perspective
Arduino: Open Source Hardware Hacking from the Software Nerd PerspectiveArduino: Open Source Hardware Hacking from the Software Nerd Perspective
Arduino: Open Source Hardware Hacking from the Software Nerd PerspectiveHoward Lewis Ship
 
Clojure: Towards The Essence of Programming
Clojure: Towards The Essence of ProgrammingClojure: Towards The Essence of Programming
Clojure: Towards The Essence of ProgrammingHoward Lewis Ship
 
Tapestry 5: Java Power, Scripting Ease
Tapestry 5: Java Power, Scripting EaseTapestry 5: Java Power, Scripting Ease
Tapestry 5: Java Power, Scripting EaseHoward Lewis Ship
 
Clojure: Functional Concurrency for the JVM (presented at OSCON)
Clojure: Functional Concurrency for the JVM (presented at OSCON)Clojure: Functional Concurrency for the JVM (presented at OSCON)
Clojure: Functional Concurrency for the JVM (presented at OSCON)Howard Lewis Ship
 
Tapestry: State of the Union
Tapestry: State of the UnionTapestry: State of the Union
Tapestry: State of the UnionHoward Lewis Ship
 
Clojure: Functional Concurrency for the JVM (presented at Open Source Bridge)
Clojure: Functional Concurrency for the JVM (presented at Open Source Bridge)Clojure: Functional Concurrency for the JVM (presented at Open Source Bridge)
Clojure: Functional Concurrency for the JVM (presented at Open Source Bridge)Howard Lewis Ship
 

Más de Howard Lewis Ship (16)

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

Último

IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century educationjfdjdjcjdnsjd
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoffsammart93
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Servicegiselly40
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfsudhanshuwaghmare1
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...Neo4j
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUK Journal
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024The Digital Insurer
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 

Último (20)

IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 

Practical Clojure Programming

  • 1. Practical Clojure Programming Howard M. Lewis Ship TWD Consulting hlship@gmail.com 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