׉?4ׁB!בCט { {u׉׉	 7cassandra://TgacbbJ8xnwXHIHagZ4zh8adtA_mkvitAHzSL3y3LA4 E` ׉	 7cassandra://9klVRoyrg9PQY011V1Ju4HOFbPsBaJkCvTlYOxgQssM`j ׉	 7cassandra://MMj0P_OExCs1vpvNguw8XlR5140oVHifW4LBA4Xo22AKH͠	Up.7`ט   {u׈         נUp.7e g6.9ׁHmailto:mj@ative.dkׁׁЈ׈EUp.7a׉E dClojure in 10 Minutes
Clojure Meet-Up Copenhagen
September 23, 2010
Martin Jul, mj@ative.dk / @mjul
׉	 7cassandra://9klVRoyrg9PQY011V1Ju4HOFbPsBaJkCvTlYOxgQssM`j Up.7bUp.7a
בCט   {u׉׉	 7cassandra://kEH8badYPSwzXIv7vP8H2unrvu53C3VZmC5hlxUskhU ` ׉	 7cassandra://9U48ovZBHDpXC1de06jifvQ0340d-YnJK4yAxTHkaOs$` j ׉	 7cassandra://fZxyOmXm4jBDyPqoArA8Hiq46m1pXXzQ8dRr7uVAbqE0j|͠	Up.7fט { {u׉׉	 7cassandra://M7VusItWP7sdUnQ8AhtiIT2lMEmwRh1L3uloYTHeLB8 t` ׉	 7cassandra://rnukfHtTOywGIPPogrk8qq_6UQRKL3L7VdmVx5JIU44$` j ׉	 7cassandra://HLjo3CmmCNVCvOB6hSqNtlILkP-8eIZ6FhlMsmo6HMMC|͠	Up/7gנUp/7l 	e@9ׁHhttp://core.clׁׁЈ׉EWhat is Clojure?
• Lisp
• Functional Programming
• Immutable, persistent data structures
• Software Transactional Memory
• Object-oriented (sort of)
• Macros
• Managed code: JVM and CLR
Clojure is the future!
-- Uncle Bob
Getting off the
Lisp Island
׉	 7cassandra://9U48ovZBHDpXC1de06jifvQ0340d-YnJK4yAxTHkaOs$` j Up/7h׉ESyntax and Data Types
; This is a comment, semicolon is similar to // in C# / Java
;; List is the most common data structure
'(1 2 3)
;; Vector is a list that is indexable by position
[1 2 3]
;; Maps are associative data structures
{:key "value", :id 42}
;; Sets are mathematical sets
#{1 2 3}
;; Expressions are lists of form (function arg-1 arg-2 ...)
(println "Hello, World")
(+ 1 2 3)
file: core.clj
List
Vector
Map
Set
Expression
׉	 7cassandra://rnukfHtTOywGIPPogrk8qq_6UQRKL3L7VdmVx5JIU44$` j Up/7iUp/7h
בCט   {u׉׉	 7cassandra://8aTxLyTNlT8ThC-qaR3ZlpN5mPv8HeXG1rWrpTkv9H0 C`׉	 7cassandra://5TQnpp8RKxqXJnuPA7yL7h5EsrGcYudiVkEWZE1WGMUu`j ׉	 7cassandra://S2IHpebEyhriQcxY4IVIlgYtSKZ2hu96QpkxiXiu5cYR)͠	Up/7mט { {u׉׉	 7cassandra://2jlnGxDIhrp_5M-dW1XtzJ9BlbdBr9oWa98lmItRYkI e`׉	 7cassandra://ZeNReWAf2tSngZLzQhk_N2nFErniVv2bOKIi2xXopIg`j ׉	 7cassandra://8hCtmskUvjHESjhFJwY0vAtYEJpH3-KvvyRXKRiVbxcf͠	Up/7nנUp/7t 	ez9ׁHhttp://functional.clׁׁЈ׉E bClojure Basics
file: functional.clj
Incidentally this could also have
been a modem connect string
׉	 7cassandra://5TQnpp8RKxqXJnuPA7yL7h5EsrGcYudiVkEWZE1WGMUu`j Up/7o׉E ,Functional Programming
file: functional.clj
׉	 7cassandra://ZeNReWAf2tSngZLzQhk_N2nFErniVv2bOKIi2xXopIg`j Up/7pUp/7o
בCט   {u׉׉	 7cassandra://d4AxTepZn-WLfti59mfWyJt8ekXkIWBsd0G2SOpeFf8 ?` ׉	 7cassandra://Gn-5a4nUyvmev1HM_j1hMtwb8ExiPnz7RUh2bOW1DmM*` j ׉	 7cassandra://QjnlZAGIevRcFHfbphvRjoEZIwaj_DJwLRdAaKFQIQA\F͠	Up/7uט { {u׉׉	 7cassandra://RBdmyKtamX-Mz84At5Z_hKiLPkxPBdugXc7MIopyff0 h` ׉	 7cassandra://c4p7plM0btjZaFjjcfUZmAzIRy0w5AW8Jhd7Hae2GnM`j ׉	 7cassandra://acKSjeZOV5IjbPJcNpmvtqGBiYyxSa7ivBGbzt1EkqU4͠	Up/7v׉E Simple and Concise
(defn blank? [s]
(every? #(Character/isWhitespace %) s))
Source: Programming Clojure by Stuart Halloway (Pragmatic Programmers, 2009)
׉	 7cassandra://Gn-5a4nUyvmev1HM_j1hMtwb8ExiPnz7RUh2bOW1DmM*` j Up/7w׉E ”State – you’re doing it wrong”
• Immutable
• Persistent (struktural sharing, not copying)
b
(def a (list 1 2 3))
(def b (rest a))
a
1
• Simpler code
• Less concurrency issues
2
3
e.g. stable
enumerations
׉	 7cassandra://c4p7plM0btjZaFjjcfUZmAzIRy0w5AW8Jhd7Hae2GnM`j Up/7xUp/7w
בCט   {u׉׉	 7cassandra://DgOaIzmLLTZ46UtbUDcnfjWfDoj5eObgQhcnaJ0Xg1s "`׉	 7cassandra://YYDBhrc4RvYd5Ymj8XP9BkfNrwkB27W_o6U0yTdhAVI*(`j ׉	 7cassandra://HsLWv3E18QxA2uW596qihdY9yViOo4i2XU_vzapXdDÍc͠	Up/7{ט { {u׉׉	 7cassandra://g5EqSV7TngEmiAPC3c-McIHI3AxNiWrt9ejFh30j64o `׉	 7cassandra://6Hvkg53VCg4lPIqbFkM4tfO1dphNg1clSNJrqXhdqkI)`j ׉	 7cassandra://H55lTJU47BH8-fi9_9BCm5XNNiafn1lBMLrIdfpAXG4͡b͠	Up/7|נUp/7 
e09ׁHhttp://oo.clׁׁЈ׉E gSTM – Software Transactional Memory
ref
1
1
2
file: stm.clj
concurrency-safe
in-memory
transactions!
׉	 7cassandra://YYDBhrc4RvYd5Ymj8XP9BkfNrwkB27W_o6U0yTdhAVI*(`j Up/7}׉E QObject Oriented with Protocols
(price-with-vat espresso)
(vat iver)
file: oo.clj
׉	 7cassandra://6Hvkg53VCg4lPIqbFkM4tfO1dphNg1clSNJrqXhdqkI)`j Up/7~Up/7}
בCט   {u׉׉	 7cassandra://ZVbATw4wYk_-BY2otW13hgD9VE64nF2RCISf66aVi1c i`׉	 7cassandra://wPvRop_n5b6LQNnUqKqdjjOXhUUaE3FZwCo0WLEMZcw"`j ׉	 7cassandra://qm3Z5kcYKK3siRpSr36oHUAAzCWnLKjP5hO64Krt_CI͖͠	Up07ט { {u׉׉	 7cassandra://PDbZAcoJ0nGLQmW0ACTQzgcduBmjPEnm1AEbvU_WeqA ` ׉	 7cassandra://2Uxw7JR9brTizysOzV1XFgxgM_TvK1xiVs1PMSZIkbE&`j ׉	 7cassandra://pbBQhq3yTJDrglqk8Txfrl-iDNvsdPYHyt5Cvijla2Q0Ef͠	Up07נUp07 yeI9ׁHhttp://multi.clׁׁЈ׉E ;Multi-methods
Not your mother’s
dispatch
file: multi.clj
׉	 7cassandra://wPvRop_n5b6LQNnUqKqdjjOXhUUaE3FZwCo0WLEMZcw"`j Up07׉E The Clojure Compiler
Text
Clojure data structures
(read stream)
Reader
AST
Macro
evaluation
(eval ast)
Compiler is
available at
runtime
Byte
code
AST
Compiler
Your hip friends call this
language homoiconic
Great for DSLs
׉	 7cassandra://2Uxw7JR9brTizysOzV1XFgxgM_TvK1xiVs1PMSZIkbE&`j Up07Up07
בCט   {u׉׉	 7cassandra://o5kwaNPGg7jtPnH3siOqLhlC9hkOXDLdO39VZdaoWnk Yy` ׉	 7cassandra://nW-Ww6Fb0X3kHeYGR57nKljrjYIzOrG_4jaw0SG-os8"` j ׉	 7cassandra://uGjCH_h7Rn-_fHnz0WEkTy1oq-Zr5x45jbEfj8X2oII4|͠	Up17נUp17 {dG9ׁHhttp://web.coׁׁЈנUp17 f9ׁH 'http://github.com/weavejester/compojureׁׁЈנUp17 ہ9ׁHhttp://compojure.roׁׁЈנUp17 gV9ׁHhttp://ring.adapter.jeׁׁЈנUp17 =9ׁHhttp://compojure.coׁׁЈ׉EXExample: Compojure web app
(ns hello-world
(:use compojure.core, ring.adapter.jetty)
(:require [compojure.route :as route]))
(defroutes main-routes
(GET "/" [] "<h1>Hello World</h1>")
(route/not-found "<h1>Page not found</h1>"))
(run-jetty main-routes {:port 8080})
Source: http://github.com/weavejester/compojure
shorter than your
web.config!
׉	 7cassandra://nW-Ww6Fb0X3kHeYGR57nKljrjYIzOrG_4jaw0SG-os8"` j Up17׈EUp17Up17
,Clojure in 10 minutess !Doh dit is de descriptionUi{.͵