You are on page 1of 23

A Brief Beginner's Guide To Clojure

by John Gabriele, last-modified: 2012-08 (uses Clojure 1.4, einin!en 2.0.0"re#ie$10, and %"enJ&' ()

*he "ur"ose of this brief !uide is to !et ne$ users +ui,-ly set u" $ith and a,,limated to the Clojure lands,a"e so they ,an then be!in $or-in! throu!h other materials to learn the lan!ua!e itself. .t/s for !ettin! started $ith Clojure. *his !uide ,on,erns the ori!inal, Ja#a-based Clojure im"lementation. *here are others. .t/s not a Clojure lan!ua!e tutorial 0 there are already a number of !ood ones a#ailable (lin-ed to later). *his !uide is not ,om"rehensi#e 0 it/s just a handful of notes that . thou!ht $ould be most useful to ne$ Clojurians. *he author (hi1) assumes you/re usin! a &ebian-based G234 inu5 distribution $ith the usual 6ash shell. .t/s intended that the ,ha"ters of this !uide be read in order. *his !uide may ,ontain errors. ./m "retty ne$ to Clojure myself. .f you find errors, or if you find somethin! missin! that you $ish someone had told you $hen you first be!an usin! Clojure 0 or if you just s"ot somethin! that/s un,lear, ,lumsy, or too #erbose 0 "lease let me -no$1 *o !et started, "lease see the table of ,ontents.

Chapter 1: General Overview

7ome .nfo 8bout Ja#a

Clojure is a lan!ua!e $ritten in Ja#a and also in Clojure itself. *he lan!ua!e im"lementation (,om"iler and runtime) is distributed as a jar file and runs on the Ja#a #irtual ma,hine (9J:;<). =ou/ll be $ritin! your "ro!rams in Clojure, $hi,h $ill be ,om"iled by the Clojure

im"lementation into J:; byte,ode and then run on the J:; (see belo$ for e5"lanations of Ja#a-related terms). Clojure ,omes $ith a 9>?@ < 0 a 9read, e#al, "rint loo"<. *his is an intera,ti#e "rom"t, li-e the @ython "rom"t, $here you ,an run Clojure ,ode and see $hat it returns. Clojure sour,e ,ode filenames end in 9.,lj<. Aor more about $hat Clojure is, see http://clojure.org/.

Some Info A out !ava


7in,e Clojure runs on the J:; and ,an intero"erate ,losely $ith Ja#a, it hel"s to -no$ a little about Ja#a. Bere are e5"lanations of some terms and also a fe$ other morsels of useful information:

Ja#a sour,e ,ode !ets ,om"iled to 9byte,ode< by a ,om"iler "ro!ram usually named 9javac< ($hi,h you $on/t need to use dire,tly $hile $or-in! $ith Clojure). *he J:; (the java ,ommand) runs byte,ode. .t doesn/t matter $here the byte,ode ,ame from 0 it ,ould/#e been ,om"iled from Ja#a sour,e, or Clojure sour,e, or some other lan!ua!e. 6yte,ode is ,ontained in 9.,lass< files. doesn/t -no$ $here to find ,lass files $hi,h aren/t "art of the Ja#a standard ,lass library. .t maintains a list of "la,es to loo- ,alled the 9,lass"ath<. *o tell java to add a lo,ation to its ,lass"ath, you $ould use the -cp path/to/classfile/dir o"tion on the ,ommand line (or less-,ommonly, set an en#ironment #ariable). *he standard Clojure "roje,t mana!ement tool (dis,ussed later) ta-es ,are of dealin! $ith the java ,ommand and the ,lass"ath so you don/t ha#e to.
java

(Note: this brief guide doesnt cover how to use Java code in your Clojure projects, except to provide a link to additional info !

Aor distribution "ur"oses, ,lass files for a !i#en library or a""li,ation are ty"i,ally "a,-ed to!ether in a 9.jar< ar,hi#e file. Jar files are not unli-e 9tar< or 9Ci"< files, and ,an ,ontain other files besides ,lass files. Just li-e you ,an tell java $here to find ,lass files usin! the -cp path/to/classfile/dir o"tion, you ,an also tell it to find them "a,-ed inside a jar file: -cp path/to/jarfile.jar. .f a jar file ,ontains a ,lass file $ith a 9main< fun,tion, and the jar file also ,ontains a s"e,ial bit of metadata indi,atin! $hi,h ,lass file that is, then the jar ,an be run by the J:; as a standalone "ro!ram li-e so: java -jar path/to/my-cool-app.jar 7o:

o o

-cp path/to/jarfile.jar

is for tellin! java to find ,lassfiles in jarfile.jar, ,ommand.

and
-jar path/to/jarfile.jar is for tellin! it to run jarfile.jar. 3sa!e of the ja#a jar ,ommand is some$hat similar to the familiar tar

7ome des-to" o"eratin! systems may let you just double-,li,- on jar files to run them. Ja#a ,omes $ith a #ery lar!e standard library, all of $hi,h is easily a,,essible from Clojure. *here are many other Ja#a libraries a#ailable as $ell, and these are also easily a,,essible from Clojure. Ja#a is readily a#ailable for most "latforms. %n &ebian-based G234 inu5 distributions it may already be installed (9o"enjd--(-jd-<). . thin- on ;7 Dindo$s you need to do$nload an installer from http://www.java.com/. %n ;a, %7 E, either it/s already installed (try java -version to see) or else you need to do$nload an installer from 8""le.

>e!ardin! the lan!ua!e itself, Ja#a is your !arden-#ariety, stati,ally-ty"ed, im"erati#e, obje,t-oriented lan!ua!e. =ou/#e !ot ,lasses, and ,an instantiate obje,ts from those ,lasses. Aun,tions ,an be defined only inside ,lasses. *here/s fun,tions you ,an ,all #ia a ,lass ($here the ,lass just a,ts as a names"a,e for the fun,tion), and there/s fun,tions you ,an ,all on behalf of an obje,t ($hi,h often modifies its state). *here are "any Ja#a tutorials out there. @ersonally, for learnin! Ja#a, . li-e the 9Core Ja#a< boo- by Borstmann F Cornell.

Chapter ": #ationale for using Clojure


Bere are some reasons $hy you mi!ht de,ide to use Clojure:

.t has a minimal and ele!ant synta5 (e5"ressions in balan,ed "arentheses, bra,-ets, F bra,es). Clojure "ro!rams run #ery +ui,-ly (the J:; is hi!hly-o"timiCed). *he lan!ua!e itself is fairly sim"le and "ra,ti,al. "o$erful lan!ua!e features (e5., ma,ros) e5,ellent ,on,urren,y su""ort easy intero"erability $ith Ja#a, "ro#idin! a,,ess to the Ja#a standard libraries and other Ja#a libs as $ell (no $ra""in! re+uired) ,ross-"latform .t has a shar", a,ti#e, and hel"ful ,ommunity. .t/s a modern $ell-thou!ht-out lan!ua!e, and it/s a lot of fun to use. :)

7ee also >i,h Bi,-ey/s rationale.

Chapter $: Installing Clojure


7hort ans$er: you don/t. :) 8s noted in the !eneral o#er#ie$, you must ha#e Ja#a installed before you ,an use Clojure. .f you don/t already ha#e it:
sudo apt-get install openjdk-7-jdk

*he Clojure im"lementation itself is just a sin!le jar file. *he Clojure "roje,ts you ,reate (des,ribed in the ne5t ,ha"ter) $ill ha#e a,,ess to a ,o"y $hi,h the "roje,t mana!ement tool automati,ally fet,hes and -ee"s around for you. 7o, althou!h you $on/t need to install Clojure, you will need to install the "roje,t mana!ement tool, and that/s des,ribed in the ne5t ,ha"ter.

Chapter %: &evelopment 'nvironment


*e5t ?ditor 7etu" Clojure @roje,ts Dor-flo$ 7ummary

Aor a s"artan yet still "rodu,ti#e set-u" to ra"idly !et you !oin!, . re,ommend for no$ just usin! a te5t editor and a terminal $indo$ or t$o. &etails belo$.

Te(t 'ditor Setup


.f you already ha#e a fa#orite modern te5t editor, just use that. ;ost should ha#e at least synta5-hi!hli!htin! su""ort for Clojure, and that/s enou!h for no$. Aor hel" !ettin! started $ith #arious editors and .&?/s see the list of lin-s at the bottom of the Clojure de# $i-i/s Gettin! 7tarted "a!e. 8 ,ommon .&? ,hoi,e is ?,li"se $ith Counter,lo,-$ise. 8 "arti,ularly "o$erful and ,onfi!urable editor that many Clojurians use is G234?ma,s. .f you/re interested, here/s a short !uide to +ui,-ly !et you !oin!.

Clojure )roje*ts
Dhene#er you $ant to start $ritin! a Clojure a""li,ation or library, it/s most ,ommon to first ,reate a ne$ project for it. 8 "roje,t is just a dire,tory (named after the "roje,t) $hi,h should ,ontain:

a "roje,t.,lj file, a >?8&;?.md file,

your sour,e ,ode, and usually other sundry files.

*he tool that/s used to ,reate and mana!e Clojure "roje,ts is ,alled einin!en (9line-in!-en<), or just 9lein< for short ($hi,h is also the name of the einin!en ,ommand-line "ro!ram). De/ll dis,uss lein in !reater detail in a later ,ha"ter. *o start tin-erin! around $ith some Clojure ,ode, $e first need to install einin!en and then use it to ,reate a little "roje,t $ithin $hi,h to $or-. Create a G4bin dir if you don/t already ha#e one (and ma-e sure it/s on your H@8*B), and install lein li-e so:
cd ~/bin wget https://raw.github.com/technomancy/leiningen/preview/bin/lein chmod ! lein lein self-install

( ein/s self-install $ill ,reate G4.lein and G4.m2 dire,tories.) 2ote that $e/re usin! lein 2.5 (stable, thou!h not yet offi,ially released), e#en thou!h the 1.5 release is also still ,ommonly used. 2o$ ,reate a little "roje,t:
cd ~/temp lein new foo-bar cd foo-bar

and start the Clojure re"l for this "roje,t:


lein repl

=ou should !et a 9userIJ< "rom"t. *y"e "clojure-version) and hit >eturn. =ou should !et ba,- 91.4.0<. 2o$ try:
"dotimes #n $%& "println 'hi' n))

and it should ,ount. 2eat1 =ou don/t a,tually need to ,reate a "roje,t in order to !et a Clojure re"l. Arom any dire,tory you li-e, you ,an just run lein repl and you/ll !et a re"l. .nstead of runnin! that ,ode in the re"l, let/s turn our "roje,t into an a"", then "ut that ,ode into our "roje,t/s main sour,e file. Airst thin!s first thou!h: $e need to s"e,ify in the "roje,t.,lj $here our a""/s 9main< fun,tion is lo,ated. Kuit the re"l (either Ctrl-d or "e!it) or "(uit), as it/s already told you :)), and o"en the "roje,t.,lj file. 8dd 9:main foo-bar.,ore< to the end, thus ma-in! it loo- li-e this:
"defproject foo-bar '%.$.%-)*+,)-./'

:description '01234: write description' :url 'http://e!ample.com/01234' :license 5:name '4clipse ,ublic 6icense' :url 'http://www.eclipse.org/legal/epl-v$%.html'7 :dependencies ##org.clojure/clojure '$.8.%'&& :main foo-bar.core)

2o$ o"en the sr,4fooLbar4,ore.,lj file. 2ote: .t/s merely an im"lementation oddity that names"a,es $ith dashes in them ,orres"ond to dire,tories $ith unders,ores in them. .n your ,ode (and your "roje,t name), use hy"hens. =ou/ll noti,e that there/s already a 9main< fun,tion (named 9-main<) in your ,ore.,lj file to !et you started. 7tart u" your re"l a!ain (lein repl). *his time the "rom"t should be 9foo-bar.,oreIJ<, sin,e $e set :main in our "roje,t.,lj file. Go ahead and run -main as-is from the re"l, li-e so:
"-main)

.t should "rint out 9Bello, Dorld1<. =ou ,an also read its do,umentation from the re"l:
"doc -main)

;odify that ,ore.,lj file to ma-e it loo- li-e this:


"ns foo-bar.core) "defn -main '1 do a little counting.' #9 args& "dotimes #n $%& "println 'hi' n)))

and sa#e it. 6a,- in the re"l, reload your ,ore.,lj file li-e so:
"re(uire :foo-bar.core :reload)

and run 9-main< (and read its do,s) a!ain. =ou should !et the u"dated #ersion. Ainally, if you li-e, you ,an also sim"ly ha#e lein run your "ro!ram $ithout the re"l. ?5it the re"l and then do lein run. *his ,auses the 9-main< fun,tion in the na"espace foo-bar.,ore ($hi,h $as set u" in "roje,t.,lj after 9:main<) to e5e,ute. =our de# en#ironment is no$ all set1 :)

+or,flow SummarDhile you/re learnin! and e5"erimentin! $ith Clojure, your $or-flo$ $ill li-ely be somethin! li-e this: 1. o"en your "roje,t/s sr,4fooLbar4,ore.,lj in your editor

2. cd into your "roje,t dire,tory and start u" the re"l (lein repl) M. intera,ti#ely run some ,ode (your 9-main< fun,tion, or other fun,tions, or fun,tions from libs that your "roje,t ma-es use of) 4. edit your ,ode, then reload it: "re(uire :foo-bar.core :reload) N. !o to ste" M

Chapter .: The /anguage


8 2ote on 2ames"a,es ;is, Ja#a 2otes

Clojure is not an obje,t-oriented lan!ua!e. Dhen someone mentions 9obje,ts< in Clojure, they/re !enerally usin! that term in the !eneri, sense (as in, 9obje,ts su,h as numbers, strin!s, fun,tions, data stru,tures, 8toms, 8!ents, et,.<) 0 not in the sense of %%-style obje,ts. Clojure is a is"-diale,t, and is also similar to other hi!h-le#el s,ri"tin! lan!ua!es you may ha#e used. *here/s built-in data stru,tures and a #ariety of handy fun,tions for o"eratin! on them. 6ut there/s one bi! differen,e: all Clojure #alues (numbers, strin!s, data stru,tures, et,.) are immutable. .f you $ant one of them ,han!ed, you instead just ma-e a 9$hole ne$< data stru,ture $ith that one small bit ,han!ed. *his isn/t as ,raCy as it sounds thou!h, be,ause 0 sin,e they/re immutable 0 Clojure ,an share data bet$een different data stru,tures. &on/t $orry if this sounds odd. %n,e you start !oin! throu!h tutorials and tryin! thin!s out it be!ins to ma-e sense ho$ it $or-s out in "ra,ti,e. 2ote: you ,an, of ,ourse, use Ja#a %%-style obje,ts in Clojure, $hi,h are usually mutable. 6ut the ,ore built-in bread-and-butter Clojure data stru,tures are all immutable. 7in,e Clojure #alues aren/t mutable, it doesn/t really ma-e sense to ,all them 9#ariables< (they don/t #ary). Clojure does, thou!h, ha#e 9referen,e ty"es< $hi,h a,t li-e #ariables. >eferen,e ty"es are mutableO you ,an ,han!e $hi,h immutable #alue they refer to. 8 ,ou"le of notes about referen,e ty"es:

they ,ome in 4 different fla#ors (:ars, >efs, 8!ents, F 8toms) the Clojure runtime hel"s you ,han!e $hat immutable #alue they refer to in a mana!ed $ay that ensures ,on,urren,y $or-s reliably.

*utorials usually dis,uss these referen,e ty"es in later se,tions, after you/#e !otten the han! of basi, idiomati, Clojure. >eferen,e ty"es are su""osed to re"resent an 9identity< 0 an entity that may ta-e on different (immutable) #alues o#er time. 6ut re!ardless of $hi,h #alue an identity ,urrently ha""ens to refer to, it/s still the sa"e entity.

A 0ote on 0amespa*es
?#ery fun,tion has a fully-+ualified name. Aor e5am"le, a fun,tion named 9my-fun,< defined in your "roje,t/s my-"roj4sr,4myL"roj4,ore.,lj file $ould ha#e a fully-+ualified name of 9my-

"roj.,ore4my-fun,<. *he "art before the slash (9my-"roj.,ore<) is the na"espace of the fun,tion. .f you ,all my-fun, from some$here $ithin ,ore.,lj, you ,an just ,all it by its sim"le name (9my-fun,<) 0 you don/t ha#e to fully-+ualify it. 6ut if you $ant to ,all my-fun, from ,ode in some other file, you ha#e to someho$ tell Clojure that you/re tal-in! about the my"roj.,ore4my-fun, fun,tion. (De/ll !et to details on ho$ to do that later, in the ,ha"ter on mana!in! and usin! libraries.) *he only e5,e"tion to that rule is: you don/t need to fully-+ualify Clojure/s built-in fun,tion names in order to ,all them. 8lthou!h their names"a,e is ,lojure.,ore, they/re al$ays a#ailable by their short names. Aor e5am"le, you ,an al$ays ,all "println 'hi') instead of "clojure.core/println 'hi').

1is* !ava 0otes


8 "arti,ular stren!th of Clojure is ho$ easily it allo$s you to use Ja#a. 8lthou!h you don/t need to -no$ Ja#a to use Clojure, it hel"s, be,ause $hene#er you run a,ross somethin! Clojure doesn/t ha#e, you ,an easily enou!h use the Ja#a solution ri!ht from your Clojure ,ode. 8nother note about Ja#a: it has 9arrays< (a fi5ed-siCe, se+uential, inde5able, mutable data stru,ture). Dhen you hear 9array<, it/s the Ja#a -ind. *he Clojure inde5able data stru,ture is ,alled 9#e,tor<.

Chapter 2: &o*umentation and #esour*es


*he ;ain Clojure &o,s %ther &o,s 6uilt-in &o,strin!s *he 7our,e ibrary 7our,e ?5am"le Code Ja#a &o,umentation %ther Debsites :ideos of *al-s 6oo-s

The 1ain Clojure &o*s


*he Clojure $ebsite ,ontains many arti,les, most of $hi,h are listed on their &o,umentation "a!e. *here/s also has a !reat ,heatsheet there ($hi,h in,ludes a lin- at the bottom to enhan,ed ,heatsheets $ith toolti"s). *he ,lojure-do,.or! site is ,urrently under de#elo"ment but already ,ontains a number of arti,les.

Aor 8@. do,umentation $ith user-submitted e5am"les, see Clojure&o,s. (=ou ,an also find the 8@. do,s at http://clojure.github.com/.) *here/s the Confluen,e $i-i, $hi,h is an enter"rise $i-i P ,ommuni,ation medium for ,ore de#elo"ers. .t ,ontains many useful and u"-to-date "a!es. *he Clojure @ro!rammin! $i-iboo- alon! $ith its sister earnin! Clojure are t$o ,ommunity-fo,used sour,es of do,umentation.

Other &o*s
%ne $ell--no$n tutorial is Clojure - Aun,tional @ro!rammin! for the J:;. *he earn Clojure site ,ontains a number of "ointers to #arious do,s, boo-s, and other ,ommunity resour,es. . also found this ,urated readin! list of useful arti,les. 8lso http://www.eddology.com/post/$8;<=;7<=></busy-persons-clojure. 8nd http://pragprog.com/maga?ines/=%$$-%7/content.

Built3in &o*strings
Clojure (li-e @ython) su""orts docstrings. *hese are strin!s embedded in the sour,e ,ode of fun,tions for the "ur"ose of do,umentin! them. =ou ,an intera,ti#ely a,,ess the do,strin! (at the re"l) for any fun,tion li-e so:
"doc func-name)

*o see a listin! of $hat/s a#ailable in a !i#en library, use:


"dir the.namespace)

=ou ,an also sear,h the do,strin!s usin! "find-doc @'search string'). 2ote that the strin! inside @'' is a re!e5.

The Sour*e
=ou ,an see the sour,e ,ode for any Clojure fun,tion ri!ht at the re"l, for e5am"le:
"source repeat)

/i rar- Sour*e

Dhen sear,hin! for do,umentation on a !i#en library, ,onsider readin! the sour,e. oo- in G4.m24re"ository for the jars. *o o"en one u", you mi!ht do this:
mkdir ~/temp/foo cp ~/.m=/repository/path/to/bar-$.%.%.jar ~/temp/foo cd ~/temp/foo jar !vf bar-$.%.%.jar

*o !enerate do,s from library sour,e ,ode, see Generatin! &o,s from ibraries.

'(ample Code
Aor e5am"le ,ode, you ,an al$ays read the sour,e ,ode files of Clojure itself (do$nload and loo- in ,lojure-i j k4sr,4,lj4,lojure). =ou mi!ht also loo- at ,ontrib and Mrd-"arty libraries (see a#ailable libraries). ;ore e5am"les:
https://github.com/wagjo/hangman https://bitbucket.org/drcabana/euler/overview http://rosettacode.org/wiki/Aategory:Alojure *he Clojure se,tion at http://pleac.sourceforge.net/

!ava &o*umentation
.t $ill sometimes be useful to loo- u" do,umentation on #arious Ja#a standard ,lasses. =ou ,ould do$nload and install the full Ja#a 8@. do,s onto your o$n system (and $ill "robably $ant to at some "oint), but for no$ you ,an a,,ess those do,s at: http://docs.oracle.com/javase/7/docs/api/.

Other +e sites
4,lojure is a site that has you $or- throu!h su,,essi#ely more diffi,ult "ro!rammin! "roblems, sol#in! them $ith Clojure.

4ideos of Tal,s
Bere/s a ,olle,tion of tal-s !i#en by >i,h Bi,-ey (,reator of Clojure). 8 number of other Clojure tal-s are a#ailable at .nfoK as $ell. *here/s also a bli".t# "a!e ,ontainin! #arious tal-s. 8 dis,ussion bet$een >i,h Bi,-ey and 6rian 6e,-man.

Boo,s

;y ,urrent fa#orite Clojure boo- is Clojure @ro!rammin!. *here are a number of others thou!h (in no "arti,ular order):

@ro!rammin! Clojure Joy of Clojure Clojure in 8,tion @ra,ti,al Clojure

Chapter 5: Getting 6elp from the Communit*he M main "la,es to !et hel" $ith Clojure, in no "arti,ular order, are:

.>C (Q,lojure at freenode) the mailin! list 4 dis,ussion !rou": http://groups.google.com/group/clojure (2ote: messa!es from ne$ members are moderated and may ta-e a little $hile to a""ear.) 7ta,-%#erflo$ Clojure +uestions

Dhen usin! .>C, if you/#e !ot e5am"le ,ode you $ish to as- about, you mi!ht "ost it to the Clojure ,ommunity/s #ery o$n >efhea" "aste-bin. *here are at least 2 bots usually residin! on Q,lojure, and they both ,an e#aluate ,ode for you: ,lojurebot 3sa!e e5am"le: B" $ $) laCybot 3sa!e e5am"le: 9" $ $) 3sa!e e5am"le $ith surroundin! te5t:

this is @@"println 'just') a test

.f you $ant to send someone on .>C a messa!e, but they/re not lo!!ed in at the moment, laCybot ,an sa#e the messa!e and deli#er it ne5t time they/re on .>C. Aor e5am"le, to send amalloy su,h a messa!e:
Cmail amalloy /hanks for the help earlierD

.f someone +ueues su,h a messa!e for you, you retrie#e it (as laCybot $ill tell you) by messa!in! laCybot li-e so:
/msg la?ybot mail

*o see $hen the last time someone sent a messa!e to the list, do:
Cseen their-nick

o!s for Q,lojure are a#ailable at http://clojure-log.n%$se.net/.

8nd, as al$ays 0 re!ardless of #enue 0 ,ourtesy ,ounts. :)

Chapter 7: Availa le Clojure /i raries


7yno"sis 7tandard ibrary Contrib ibraries from Clojars ibraries from ;a#en Central Ja#a 7tandard ibrary: J&' %ther Ja#a ibraries &efun,tR

ibraries a#ailable for use $ith Clojure in,lude:


,lojure.,ore (the fundamental built-in library of the Clojure lan!ua!e) its o$n standard libraries (these ,ome $ith Clojure) the ,ontrib libraries (standard, but they don/t shi" $ith Clojure) Mrd-"arty Clojure libs (a#ailable #ia Clojars) Mrd-"arty J:; libs (a#ailable #ia ;a#en Central) Ja#a standard ,lass library (,omes standard $ith Ja#a) other Ja#a libs

(.nstallation and usa!e is ,o#ered in the ne5t ,ha"ter.)

S-nopsis
t-pe of li ,ore standard lib ,ontrib Mrd "arty Ja#a std lib J:; jar namespa*e standard8 lo*ation ,lojure.,ore built-in ,lojure.foo ,omes $ith Clojure ,lojure.foo "roje,ts at !ithub, jars #ia ;a#en Central (#arious) "roje,ts at !ithub, jars #ia Clojars (#arious) ,omes $ith Ja#a (#arious) ;a#en Central

Standard /i rar.n addition to ,lojure.,ore, Clojure ,omes $ith a number of standard libraries. *hey/re all listed (alon! $ith their do,umentation) at http://clojure.github.com/clojure/inde!.html. i-e ,lojure.,ore, their names"a,e names all start $ith 9,lojure.< .f you do$nload the Clojure release and loo- in its 9,lojure-i.j.-4sr,4,lj4,lojure< dir, you ,an see the sour,e ,ode files for these libs.

Contri
Clojure also has a number of standard e5tra libs (9,ontrib< libraries) $hi,h are not distributed $ith Clojure "ro"er. *hey all:

are listed at the Clojure Contrib Confluen,e $i-i "a!e. ha#e names"a,e names that start $ith 9,lojure.<, just li-e the standard libs. ha#e do,umentation a#ailable at http://clojure.github.com/. li#e at !ithub as se"arate "roje,ts under the same 9,lojure< user as Clojure itself. *he !ithub "roje,t names are the names"a,e names minus the 9,lojure.< "refi5 (so, for e5am"le, the 9al!o.!eneri,< ,ontrib lib uses the names"a,e 9,lojure.al!o.!eneri,< and li#es at https://github.com/clojure/algo.generic). are o$ned by their author as $ell as by >i,h Bi,-ey, as "er the Clojure C8 (9Contributor 8!reement<).

2ote that, ba,- in Clojure #ersion 1.2, ,ontrib had "re#iously been one bi! re"ository (9monolithi, ,ontrib<), rather than indi#idual ones li-e $e ha#e today (9modular ,ontrib<). 3nfortunately, the ,ontrib lin- at Clojuredo,s still "oints to a "a!e for the old monolithi, ,ontrib. *o read more about the ,han!e, see DhereP&idPContribPGo.

/i raries from Clojars


*here are many libraries a#ailable for Clojure at Clojars. Clojars is the 9C@82 for Clojure<, e5,e"t that only basi, information about a !i#en "roje,t is dis"layed there (su,h as a short des,ri"tion, "roje,t url, and some te,hni,al info ne,essary for usin! the "roje,t). *o read more about a !i#en "roje,t, follo$ the lin- to its "roje,t "a!e ($hi,h is usually at !ithub). .f a !i#en "roje,t is hosted at !ithub, but there/s no !ithub lin- at its ,lojars "a!e, you ,an hel" the ,ommunity by ,onta,tin! the author and lettin! them -no$ their "roje,t may be missin! a 9:url< o"tion in its "roje,t.,lj file (more details on $hat that means in the ne5t ,ha"ter). 7ome libraries may also be "art of an 9umbrella "roje,t< (for e5am"le, Clojure$er-s). 8 final note about Clojure library names: some of them are "refi5ed $ith 9,lj-<, as in 9,ljfoo<. *his ty"i,ally indi,ates that the Clojure library $ra"s a Ja#a library (in this made u" e5am"le, ,lj-foo $ra"s the 9foo< Ja#a library).

/i raries from 1aven Central


*here are also many libraries a#ailable for use by Clojure at ;a#en Central. ;a#en Central is the 9C@82 for the J:;<. (.n,identally, the ,ontrib libraries are a,tually hosted at ;a#en Central rather than at Clojars.) *o find the libraries you need, you mi!ht bro$se around at:
http://projects.apache.org/

http://www.eclipse.org/projects/ http://www.jboss.org/projects

*hose ,olle,tions are lar!e, and may host both libraries and tools 0 $ith some tools ha#in! ,om"onent libraries that you mi!ht find useful as $ell. .n,identally, the Clojure on J6oss a"" ser#er is .mmutant.

!ava Standard /i rar-: !&9


Clojure ,an, of ,ourse, use Ja#a/s built-in library (its standard ,lass library). 7ee the Ja#a do,umentation for $hat/s a#ailable. Ja#a intero" is fairly sim"le (thou!h not dis,ussed in this !uide), and 0 as $ith the Clojure standard libraries 0 there/s no e5tra installation re+uired sin,e you already ha#e Ja#a installed.

Other !ava /i raries


=ou ,an use Ja#a libraries e#en if they/re not listed at ;a#en Central, but doin! so is beyond the s,o"e of this do,ument.

&efun*t8
*here are a number of libraries listed at (lin-ed to from ,lojure.or!), but my understandin! is that that list is "retty an,ient needs to be either u"dated or remo#ed.
http://dev.clojure.org/display/community/6ibraries

Chapter :: 1anaging and ;sing /i raries in -our )roje*ts


einin!en Aindin! the ibraries =ou Dant ;ana!in! libs your "roje,t de"ends u"on o 8 2ote on 2ames o 3sin! 7tandard ibraries o 3sin! Contrib ibraries o 3sin! ibraries from Clojars &o$nloadin! jars from Clojars o 3sin! :arious Ja#a ibraries :ie$in! the &e"enden,y *ree

Clojure "ro!rams may rely on e5ternal libraries in order to run. .f you/re $ritin! su,h a Clojure "ro!ram, your users $ould need to ha#e these libraries in order to run the "ro!ram.

Clojure libraries may ma-e use of and rely on other libraries. .f you/re $ritin! su,h a Clojure library, other "ro!rammers $ho $ould li-e to use your library $ould need some $ay to install it as $ell as install any other libs that yours de"ends u"on. *he $ay Clojure handles these issues is: 1. 8 Clojure a""li,ation is ty"i,ally distributed in a jar file $hi,h in,ludes all of the a""/s de"enden,ies, in,ludin! the Clojure jar itself. 2. 8 Clojure library is distributed as a jar file. .n "ra,ti,e, libraries are most often fet,hed from Clojars or ;a#en Central (or some other re"ository) by the einin!en tool (see belo$), $hi,h also re,ursi#ely fet,hes any de"enden,ies.

/einingen
8s dis,ussed briefly in the de# en#ironment ,ha"ter, the tool used for mana!in! your Clojure "roje,ts is ,alled 9 einin!en<. ein ,an do a number of "roje,t-related tas-s, in,ludin!:

,reate ne$ "roje,ts fet,h de"enden,ies for your "roje,t (storin! them in your G4.m2 dir) build and run your "roje,t/s ,ode run your "roje,t/s tests start a Clojure >?@ (either s"e,ifi,ally for your "roje,t or else not asso,iated $ith any "roje,t in "arti,ular) "a,-a!e your "roje,t as a jar ($hether it/s a library or an a"") sho$ you your "roje,t/s ,lass"ath !enerate a ma#en-style 9"om< file for your "roje,t

*here/s also a number of a#ailable "lu!-ins that e5tend lein to su""ort additional ,ommands. *he einin!en readme and tutorial e5"lain the details of installin! and usin! lein. 8 fe$ ,omments:

is a standalone "ro!ram (a shell s,ri"t $hi,h uses the lein jar $hi,h it installs into G4.lein). ?5,e"t for lein new, you ty"i,ally only e#er run lein from inside a "roje,t dire,tory. Dhen you ,reate a ne$ "roje,t (#ia lein new my-proj), lein starts you off by ,reatin! a 9"roje,t.,lj< file in your ne$ly-,reated "roje,t dire,tory. *his is the "roje,ts"e,ifi, 9,onfi! file< that lein uses to mana!e your "roje,t.
lein

Dhen you install lein, it ,reates G4.lein and G4.m24re"ository dire,tories. *he G4.m24re"ository dir is used for ,a,hin! jars that lein fet,hes for your "roje,ts, and the lein do,s refer to it as 9the lo,al re"ository<. *he lein tutorial mentions 8nt and ;a#en. *hese are Ja#a-land tools for buildin! Ja#a "roje,ts (remember, Ja#a files also !et ,om"iled to Ja#a byte,ode). ein a,tually uses the ;a#en library under the hood. ;ana!in! your Clojure "roje,ts may entail ,om"ilin!4ahead-of-time-,om"ilin! Clojure (and "ossibly e#en Ja#a) ,ode, or ma-in! use of Ja#a libraries S and lein mana!es all of this for you. :)

*he einin!en !ithub "roje,t ,ontains a lar!e sam"le "roje,t.,lj file $hi,h you may find informati#e $hen loo-in! for details on usin! a "arti,ular :o"tion in your "roje,t.,lj. *here/s a lein dis,ussion !rou" and an .>C ,hannel: Qleinin!en at freenode. 7ome +ui,- notes on a fe$ of the lein sub,ommands (see lein help for the list of all of them): lein install is for installin! a lib you/re de#elo"in! into your o$n G4.m24re"ository, su,h that some other "roje,t you/re de#elo"in! 0 $hi,h de"ends u"on this lib 0 ,an use it e#en thou!h it hasn/t yet been made a#ailable at Clojars. lein de"s $ould ,ause lein to do$nload your "roje,t/s de"enden,ies, thou!h, you should ne#er need to run this sub,ommand e5"li,itly (e5,e"t for #ie$in! the de"enden,y tree), as lein ta-es ,are of it for you automati,ally. lein sear,h .f you use this sub,ommand, it $ill ta-e a $hile to run the first time (sin,e it must do$nload the rather lar!e sear,h inde5). . re,ommend instead usin! the Clojars4;a#en-Central sear,h forms. .n addition to lein deps, you should also ne#er need to e5"li,itly run the compile or javac sub,ommands. ein $ill ta-e ,are of them automati,ally, if ne,essary.

<inding the /i raries =ou +ant


.f you don/t see $hat you need in ,lojure.,ore, the standard library, or ,ontrib, ha#e a loo- at:

the Clojure &inin! Car the Clojure *oolbo5 Clojure7"here

8nd, of ,ourse, don/t be afraid to as- for re,ommendations on .>C. :)

1anaging li s -our proje*t depends upon


.f you/#e found a library that you $ish to use in your "roje,t, you must first edit your "roje,t.,lj file and add it so that lein -no$s your "roje,t de"ends u"on it. *he format for s"e,ifyin! a library de"enden,y loo-s li-e this:
#group-id/artifact-id version-string&

and is sometimes referred to as the 9,oordinates< of the de"enden,y. *he !rou"-id indi,ates $ho/s asso,iated $ith that "arti,ular library. *he artifa,t-id is the library name (the !rou"-id is o"tional if it/s the same as the artifa,t-id). *he #ersion strin! follo$s the ,ommon 9major.minor."at,h< "attern (e5. 91.0.2<).

Bere/s an e5am"le:
#org.clojure/data.json '%.$.E'&

2ote that the ,on#ention for most libs at Clojars (the ,anoni,al ones that you/ll usually be usin!) is to ha#e the !rou"-id be the same as the artifa,t-id. 8nd in that ,ase, the !rou"-id is omitted from the ,oordinates. .f you see a "roje,t at ,lojars $ith a !rou"-id li-e 9or!.,lojars.userna"e<, it usually indi,ates that the "roje,t is a for-ed #ersion of the ,anoni,al one. 8nother re+uirement for usin! a library is that you must edit your sour,e file to ma-e the lib a#ailable from $ithin your ,ode. ?5am"les are !i#en belo$ on ho$ to use ea,h of se#eral ty"es of a#ailable libraries. *he e5am"les belo$ are sho$n usin! the sim"le 9foo-bar< "roje,t $e ,reated in the de# en# setu" ,ha"ter.

A Note on Names
*here are at least a fe$ names asso,iated $ith ea,h library:

Its artifa*t3id> *his is at the to" of the library/s "roje,t.,lj (sometimes also "re,eeded by a !rou"-id then a slash). Its githu proje*t name> ;ost Clojure lib re"os are hosted at !ithub, and most of them are named the same as their artifa,t-id. The namespa*es it provides> *hese are $hat you s"e,ify in your sour,e ,ode in order to use the library. Aor libraries $hi,h only "ro#ide one names"a,e, it/s often 9the#artifact#id.,ore<. 2ote that the ,ontrib libs ha#e names"a,es $hi,h be!in $ith 9,lojure.<, thou!h their artifa,t-ids do not (see the e5am"le belo$).

Using Standard Libraries


*o use standard libraries in your ,ode you don/t need to tou,h your "roje,t.,lj file sin,e these libs already ,ome $ith Clojure. Just edit your ,ore.,lj file. Aor e5am"le, you ,an use the ,lojure.strin! standard lib li-e this:
"ns foo-bar.core ":re(uire #clojure.string :as str&)) "defn -main 'docstring goes here' #9 args& "println "str/reverse 'encoded secretD')))

(2ote that $e/re usin! 9str< here as an alias for ,lojure.strin! to sa#e oursel#es some ty"in!.) &o lein run to try it out.

Using Contrib Libraries


8ll the ,ontrib libs ha#e "roje,t "a!es at !ithub (under https://github.com/clojure), $ith artifa,ts (jars) hosted at ;a#en Central. *o use one 0 for e5am"le, data.json 0 $e first need to loo- u" some info about it so $e ,an ,om"ose the line that $ill need to !o into our "roje,t.,lj. =ou ,an find this information in a ,ou"le of $ays: 1. Go to the ,ontrib lib/s !ithub "roje,t "a!e. *he >?8&;?.md there should tell you e#erythin! you/ll need. 6ut if that info is someho$ missin! from the >?8&;?.md, 2. 8t ;a#en Central, ty"e 9data.json< into the sear,h field there and hit 7ear,h. *his $ill tell you that the !rou"-id is 9or!.,lojure<, the artifa,t-id is 9data.json<, and the latest #ersion is 90.1.M<. 8dd that to your "roje,t.,lj/s :de"enden,ies list:
"defproject foo-bar '%.$.%-)*+,)-./' :description '01234: write description' :url 'http://e!ample.com/01234' :license 5:name '4clipse ,ublic 6icense' :url 'http://www.eclipse.org/legal/epl-v$%.html'7 :dependencies ##org.clojure/clojure '$.8.%'& #org.clojure/data.json '%.$.E'&& :main foo-bar.core)

and ma-e your ,ore.,lj loo- li-e:


"ns foo-bar.core ":re(uire #clojure.data.json :as json&)) "defn -main 'docstring goes here' #9 args& "println "json/json-str 5:a #$ = E& :b '-ello'7)))

(2ote that $e/re usin! 9json< here as an alias for ,lojure.data.json to sa#e oursel#es some ty"in!.) &o lein run to try it out. 2ote that lein is smart 0 it noti,ed that your "roje,t needed the data.json jar, so it automati,ally $ent and fet,hed it for you. oo- in the G4.m24re"ository4or!4,lojure4data.json dir and see for yourself.

Using Libraries from Clojars


.f you/#e found a library you/re interested in at Clojars, the Clojars "a!e for the lib should sho$ you e5a,tly $hat you need to add to your "roje,t.,lj/s :de"enden,ies list. 8s noted abo#e, for ,anoni,al Mrd-"arty libs at Clojars, it/s ,ommon that the !rou"-id $ill be the same as the artifa,t-id, and so $ould be omitted in the 9,oordinates< strin! you add to your "roje,t.,lj.

.n your ,ore.,lj file, you/ll often "ut somethin! li-e 9":re(uire lib-name.core)< in your ns ma,ro, and then later use a fun,tion from that library li-e so: "lib-name.core/funcname ...)

*he Clojars "a!e for the lib should also ,ontain a lin- to the !ithub (or other home) "a!e for the library, $hi,h should ,ontain a >?8&;? sho$in! e5am"le usa!e. .f there is no su,h lin-, ,onsider sear,hin! for the lib at !ithub and then filin! a bu! re"ort at the lib/s "roje,t "a!e about the issue.

Downloading jars from Clojars


.f you $ant to dire,tly do$nload jar files from Clojars, loo- in http://clojars.org/repo/.

Using Various Java Libraries


7ear,h ;a#en Central for the library you/re interested in, and adjust your "roje,t.,lj/s :de"enden,ies just li-e ho$ you did $hen usin! a ,ontrib library. 8s for usin! Ja#a libs $hi,h are not re!istered at ;a#en Central, see the lein re"eatability do,/s 9Aree-Aloatin! Jars< se,tion.

4iewing the &ependen*- Tree


Aor a !i#en "roje,t, to see the $hi,h libraries de"end u"on $hi,h, "rint out the de"enden,y tree li-e so:
lein deps :tree

Chapter 1?: Generating &o*s from /i raries


=ou/#e ,hosen some libs that you mi!ht be able to use in your "roje,t. =ou/#e added them as de"enden,ies to your "roje,t.,lj, lein has fet,hed them for you, and no$ you/d li-e to learn more about them. %ne $ay to do that is to use ;ar!inalia to !enerate do,s from the library. ;ar!inalia "resents ,omments and do,strin!s side-by-side $ith the library sour,e ,ode. .nstall lein-mar!inalia li-e so:
cd ~/.lein touch profiles.clj

and add the follo$in! to that file:


5:user 5:plugins ##lein-marginalia '%.7.$'&&77

(or $hate#er the ,urrent #ersion of mar!inalia is.) *hen (in your "roje,t) run the lein sub,ommand4tas- "ro#ided by that "lu!-in, li-e so:
cd path/to/my-proj lein marg

and "oint your bro$ser to file://path/to/my-proj/docs/uberdoc.html. 6*D, to ma-e your own "ro!rams yield ni,e do,s $hen usin! ;ar!inalia, ,omment them usin! double-semi,olon ,omment mar-ers and usin! ;ar-do$n formattin!. 3se ;ar-do$n in your do,strin!s as $ell.

Chapter 11: &istri uting a Clojure )rogram


8s mentioned in the "re#ious ,ha"ter, Clojure "ro!rams (and Ja#a "ro!rams as $ell) are ty"i,ally distributed as re!ular jar files that ,an be run dire,tly by the J:; (for e5am"le: java -jar my-prog.jar). 7ome %7/s $ill e#en do that for you if you double-,li,- on the jar. *his ,ha"ter runs throu!h an e5am"le of ho$ you $ould ,reate and distribute a small ,ommand-line Clojure "ro!ram to a friend. Aor our e5am"le, $e/ll ,reate a tri#ial little "ro!ram that just ,ounts u" to a !i#en number ($hi,h you "ass to it), then +uits. &o this: 1. Create a ne$ "roje,t to ,ontain your "ro!ram. De/ll ma-e a ne$ 9a""<-ty"e "roje,t and ,all it 9,ount-to<:
=. cd ~/dev/clojure lein new app count-to

*his $ill ,reate a ne$ dire,tory named 9,ount-to< ,ontainin!:


count-to/ F-- .gitignore F-- project.clj F-- G4+H34.md F-- src F I-- countJto F I-- core.clj I-- test I-- countJto I-- coreJtest.clj

M. =our src/countJto/core.clj file $ill start off fairly em"ty. ;a-e it loosomethin! li-e this:
8. "ns count-to.core ;. ":gen-class))

K. 7. "defn print-usage >. #& <. "println ',lease pass this program a number to count to. Luitting.')) $%. $$. "defn count-to $=. 'Ho some counting.' $E. #n& $8. "dotimes #i n& $;. "/hread/sleep $%%%) $K. "println i))) $7. $>. "defn -main $<. '1 don:t do a whole lot ... yet.' =%. #9 args& =$. "if args ==. "count-to "1nteger/parse1nt "first args))) "print-usage)))

2M. ;a-e your "roje,t/s "roje,t.,lj file loo- li-e this:

=8. "defproject count-to '%.$.%' =;. :description 'Aounts to the number you give itB then (uits.' =K. :url 'http://e!ample.com/01234' =7. :license 5:name '4clipse ,ublic 6icense' =>. :url 'http://www.eclipse.org/legal/epl-v$%.html'7 =<. :dependencies ##org.clojure/clojure '$.8.%'&& :main count-to.core)

M0. Arom your count-to "roje,t dir, run lein uberjar. =ou should !et out"ut similar to this:
E$. E=. EE. E8. E;. EK. johnMfoil:~/dev/clojure/count-toC lein uberjar Aompiling count-to.core Aompilation succeeded. Areated /home/john/dev/clojure/count-to/target/count-to-%.$.%.jar 1ncluding count-to-%.$.%.jar 1ncluding clojure-$.8.%.jar Areated /home/john/dev/clojure/count-to/target/count-to-%.$.%standalone.jar

M(. >un your "ro!ram to try it out:


E>. cd target java -jar count-to-%.$.%-standalone.jar 8

.t should do some ,ountin! and then +uit. =ay1 MT. .f you/re ha""y $ith it, just !et that count-to-%.$.%-standalone.jar file to your friend. *hey ,an run it usin! the same ,ommand you just did. =our friend $ill, of ,ourse, need to ha#e a Ja#a runtime already installed on their system. =our friend $ill not need Clojure installed thou!h, sin,e you/#e in,luded that for them in your jar file. Optional final step: .f you $ant your friend to be able to sim"ly run, say, 9count-to 8< instead of ha#in! to al$ays ty"e out 9java -jar count-to-%.$.%-standalone.jar 8<, ,reate the follo$in! tiny s,ri"t (named 9,ount-to<) to a,,om"any the jar file:
@D/bin/bash

java -jar ~/bin/count-to-%.$.%-standalone.jar CM

;a-e it e5e,utable:
chmod ! count-to

and ha#e your friend ,o"y it 0 alon! $ith the jar file 0 to their ~/bin dire,tory. 2o$ they should be able to sim"ly ty"e
count-to 8

at their terminal for it to $or-. :)

Chapter 1": Than,s


*han-s (ne$est at the to") to:

mi,haelbarton for "ointin! out old ,ontrib lin- at ,lojuredo,s.or! Colin James for his libs and names"a,es blo! "ost, and for u"datin! it for Clojure 1.4.
:H

#ijay-iran on Q,lojure for sho$in! me ho$ to reload ,ode from the re"l, and 5e+i for lein deps :tree. 7ome lin-s from 2e$bie/s Guide to earnin! Clojure blo! "ost. *ed 6ra,ht, for the reminder to in,lude some ,omments about Ja#a/s ,lass"ath. $ea#ejester, for feedba,- and ,orre,tions on B2. te,hnoman,y, *im;C, amalloy, rae-, antares, de#n, ibd-no5, sean,orfield, >aynes, brehaut, hiredman, and others for feedba,- and ,orre,tions on Q,lojure. 6rad u,as, for his e5am"le, $hi,h . follo$ed to !et ,ommand-line ar! "assin! $or-in!.

Chapter 1$: Changes


2012-10-08 0 use of #clojure.string :as str& is "retty ,ustomary. 8lso added lin- to ,lojure-do,.or!. 2012-08-2M 0 added 98 2ote on 2ames< to the library usa!e ,ha"ter. >emo#ed unne,essary 97ummary of 2e$ @roje,t 7etu"< from de# en# ,ha"ter. 8lso u"dated to usin! lein 2.0.0"re#ie$8. 2012-08-02 0 u"dated to lein 2.0.0-"re#ie$( (you ,an no$ tell lein $hat ty"e of ne$ "roje,t to ,reate)

2012-0(-1( 0 8dded a lin- to the !enerated ,ontrib a"i do,s. 2012-0U-2T 0 2ote about monolithi, #s. modular ,ontrib, and about old lin- at ,lojuredo,s.or!. 2ote about 9,lj-< "refi5 in lib names. .m"ro#ed info on Clojars and ho$ it dis"lays des,ri"tion and url info. 3sed u"dated Gouda $ith ni,er stylin!. 2012-0U-2U 0 2ote about !rou"-id/s at ,lojars. 8lso do$nloadin! jars dire,tly from ,lojars4re"o. 2012-0U-21 0 8dded source to do,s "a!e. 8dded syno"sis table to a#ailable libs ,ha"ter. :arious minor tunin! and #ersion bum"in!. 2012-0N-18 0 remo#ed s"e,ifi, ,onfi! for ubuntu 2012-0N-08 0 added bit to &e# ?n# ,ha"ter about G4bin and your H@8*B. 2012-0N-0( 0 remo#ed ,ha"ter on ,reatin! libs. *hat "robably belon!s else$here. 2012-0N-02 0 2o$ $ith Clojure synta5 hi!hli!htin!. :) 2012-04-2( 0 8dded lin- to @ ?8C, $hi,h has a Clojure se,tion. 2012-04-2M 0 8dded some e5tra instru,tions for usin! ur5#t. ;entioned installin! rl$ra" before lein. 3"dates to $or-in! $ith lein-oneoff. 7ome minor $ordin! t$ea-s. 2012-04-1T 0 3"dated the 6rief Guide usin! the ne$ 2012.04.1T Gouda release. 2012-04-02 0 8dded some lin-s to #ideos on the do,s F resour,es "a!e 2012-0M-2M 0 8dded note on inde5 about im"lementations. 2012-0M-21 0 added notes about ,lass"ath to the !eneral-o#er#ie$ ,ha"ter 2012-0M-1M 0 remo#ed ?ma,s se,tion and "ut it into its o$n do,ument 2012-0M-12 0 initial #ersion

You might also like