(first '(clojure.))
DESCRIPTION
An introduction to Clojure I held at the Valtech Tech Day 2012.TRANSCRIPT
![Page 1: (first '(Clojure.))](https://reader033.vdocuments.net/reader033/viewer/2022060111/5564af3ad8b42a3e618b475d/html5/thumbnails/1.jpg)
(first '(Clojure.))
![Page 2: (first '(Clojure.))](https://reader033.vdocuments.net/reader033/viewer/2022060111/5564af3ad8b42a3e618b475d/html5/thumbnails/2.jpg)
Clojure is
A dynamic,
LISP-based
programming language
running on the JVM
![Page 3: (first '(Clojure.))](https://reader033.vdocuments.net/reader033/viewer/2022060111/5564af3ad8b42a3e618b475d/html5/thumbnails/3.jpg)
Origin
2007, Rich Hickey
.. 1958, John McCarthy
![Page 4: (first '(Clojure.))](https://reader033.vdocuments.net/reader033/viewer/2022060111/5564af3ad8b42a3e618b475d/html5/thumbnails/4.jpg)
Features
Functional
Homoiconic
Immutability
![Page 5: (first '(Clojure.))](https://reader033.vdocuments.net/reader033/viewer/2022060111/5564af3ad8b42a3e618b475d/html5/thumbnails/5.jpg)
Plus
Concurrency
Pragmatism
Java Interop
![Page 6: (first '(Clojure.))](https://reader033.vdocuments.net/reader033/viewer/2022060111/5564af3ad8b42a3e618b475d/html5/thumbnails/6.jpg)
Fun!
![Page 7: (first '(Clojure.))](https://reader033.vdocuments.net/reader033/viewer/2022060111/5564af3ad8b42a3e618b475d/html5/thumbnails/7.jpg)
Syntax
![Page 8: (first '(Clojure.))](https://reader033.vdocuments.net/reader033/viewer/2022060111/5564af3ad8b42a3e618b475d/html5/thumbnails/8.jpg)
Homoiconic
(+ 1 1)
● Uniform Prefix Notation● List Processing (LISP)● Code is Data
=> Predictable!
![Page 9: (first '(Clojure.))](https://reader033.vdocuments.net/reader033/viewer/2022060111/5564af3ad8b42a3e618b475d/html5/thumbnails/9.jpg)
Scalars
\c ; characters"Hello" ; strings
42 ; numbers3/2 ; ratios
true ; booleans
nil
![Page 10: (first '(Clojure.))](https://reader033.vdocuments.net/reader033/viewer/2022060111/5564af3ad8b42a3e618b475d/html5/thumbnails/10.jpg)
Names
; symbols ; keywords
i :nameprintln :when+empty?next-state.toUpperCase
![Page 11: (first '(Clojure.))](https://reader033.vdocuments.net/reader033/viewer/2022060111/5564af3ad8b42a3e618b475d/html5/thumbnails/11.jpg)
Collections
![Page 12: (first '(Clojure.))](https://reader033.vdocuments.net/reader033/viewer/2022060111/5564af3ad8b42a3e618b475d/html5/thumbnails/12.jpg)
Lists
(println "Hello")
(first '(println "Hello"))
![Page 13: (first '(Clojure.))](https://reader033.vdocuments.net/reader033/viewer/2022060111/5564af3ad8b42a3e618b475d/html5/thumbnails/13.jpg)
Vectors
["bag" "of" 4 "chips"]
![Page 14: (first '(Clojure.))](https://reader033.vdocuments.net/reader033/viewer/2022060111/5564af3ad8b42a3e618b475d/html5/thumbnails/14.jpg)
Hash-maps
{:name "Intro" :date "2012-05-29"}
![Page 15: (first '(Clojure.))](https://reader033.vdocuments.net/reader033/viewer/2022060111/5564af3ad8b42a3e618b475d/html5/thumbnails/15.jpg)
Sets
#{"unique" "snowflakes"}
![Page 16: (first '(Clojure.))](https://reader033.vdocuments.net/reader033/viewer/2022060111/5564af3ad8b42a3e618b475d/html5/thumbnails/16.jpg)
Special Forms
![Page 17: (first '(Clojure.))](https://reader033.vdocuments.net/reader033/viewer/2022060111/5564af3ad8b42a3e618b475d/html5/thumbnails/17.jpg)
Define
(def i 1)
![Page 18: (first '(Clojure.))](https://reader033.vdocuments.net/reader033/viewer/2022060111/5564af3ad8b42a3e618b475d/html5/thumbnails/18.jpg)
If
(if true (/ 1 1) (/ 1 0))
![Page 19: (first '(Clojure.))](https://reader033.vdocuments.net/reader033/viewer/2022060111/5564af3ad8b42a3e618b475d/html5/thumbnails/19.jpg)
Functions
(fn [name] (str "Hello " name "!"))
![Page 20: (first '(Clojure.))](https://reader033.vdocuments.net/reader033/viewer/2022060111/5564af3ad8b42a3e618b475d/html5/thumbnails/20.jpg)
Named Functions
(def greet (fn [name] (str "Hello " name)))
![Page 21: (first '(Clojure.))](https://reader033.vdocuments.net/reader033/viewer/2022060111/5564af3ad8b42a3e618b475d/html5/thumbnails/21.jpg)
The defn macro
(defn greet [name] (str "Hello " name))
![Page 22: (first '(Clojure.))](https://reader033.vdocuments.net/reader033/viewer/2022060111/5564af3ad8b42a3e618b475d/html5/thumbnails/22.jpg)
Let the local names in
(defn greet [name] (let [greeting "Hello" out (str greeting " " name)] out))
![Page 23: (first '(Clojure.))](https://reader033.vdocuments.net/reader033/viewer/2022060111/5564af3ad8b42a3e618b475d/html5/thumbnails/23.jpg)
Sugared Lambdas
#(str %1 %2)
; same as(fn [a1 a2] (str a1 a2))
![Page 24: (first '(Clojure.))](https://reader033.vdocuments.net/reader033/viewer/2022060111/5564af3ad8b42a3e618b475d/html5/thumbnails/24.jpg)
The rest is just eval/apply
![Page 25: (first '(Clojure.))](https://reader033.vdocuments.net/reader033/viewer/2022060111/5564af3ad8b42a3e618b475d/html5/thumbnails/25.jpg)
Basic Usage
=> represents results
![Page 26: (first '(Clojure.))](https://reader033.vdocuments.net/reader033/viewer/2022060111/5564af3ad8b42a3e618b475d/html5/thumbnails/26.jpg)
Vectors
(def items [1 2 3])
(first items)=> 1
(rest items)=> (2 3)
(items 0)=> 1
![Page 27: (first '(Clojure.))](https://reader033.vdocuments.net/reader033/viewer/2022060111/5564af3ad8b42a3e618b475d/html5/thumbnails/27.jpg)
Adding to collections
(cons items [3 4])=> [1 2 3 4]
(conj items 3)=> [1 2 3]
![Page 28: (first '(Clojure.))](https://reader033.vdocuments.net/reader033/viewer/2022060111/5564af3ad8b42a3e618b475d/html5/thumbnails/28.jpg)
Map/Reduce
(map #(+ % 1) [1 2 3])=> (2 3 4)
(reduce #(- %1 %2) [1 2 3])=> -4
![Page 29: (first '(Clojure.))](https://reader033.vdocuments.net/reader033/viewer/2022060111/5564af3ad8b42a3e618b475d/html5/thumbnails/29.jpg)
For Comprehension
(for [i (range 1 7) :when (even? i)] (str "item-" i)))
=> ("item-2" "item-4" "item-6")
![Page 30: (first '(Clojure.))](https://reader033.vdocuments.net/reader033/viewer/2022060111/5564af3ad8b42a3e618b475d/html5/thumbnails/30.jpg)
Composing Data
![Page 31: (first '(Clojure.))](https://reader033.vdocuments.net/reader033/viewer/2022060111/5564af3ad8b42a3e618b475d/html5/thumbnails/31.jpg)
Constructs
(def persons [{:id 1 :name "Some Body"} {:id 2 :name "Some Other"}])
(let [person (persons 0)] (person :name))
=> "Some Body"
![Page 32: (first '(Clojure.))](https://reader033.vdocuments.net/reader033/viewer/2022060111/5564af3ad8b42a3e618b475d/html5/thumbnails/32.jpg)
The key is getting the value
(:name (first persons))=> "Some Body"
(map :name persons)=> ("Some Body" "Some Other")
![Page 33: (first '(Clojure.))](https://reader033.vdocuments.net/reader033/viewer/2022060111/5564af3ad8b42a3e618b475d/html5/thumbnails/33.jpg)
Records
(defrecord Person [id name])
(let [person (Person. 1 "Some Body")] (:name person))
=> "Some Body"
![Page 34: (first '(Clojure.))](https://reader033.vdocuments.net/reader033/viewer/2022060111/5564af3ad8b42a3e618b475d/html5/thumbnails/34.jpg)
Destructuring
(let [{id :id name :name} person] [id name])
=> [1 "Some Body"]
![Page 35: (first '(Clojure.))](https://reader033.vdocuments.net/reader033/viewer/2022060111/5564af3ad8b42a3e618b475d/html5/thumbnails/35.jpg)
Compose Data, Compose Functions
Data first
Collections
Flow
Abstractions
![Page 36: (first '(Clojure.))](https://reader033.vdocuments.net/reader033/viewer/2022060111/5564af3ad8b42a3e618b475d/html5/thumbnails/36.jpg)
Concurrency
![Page 37: (first '(Clojure.))](https://reader033.vdocuments.net/reader033/viewer/2022060111/5564af3ad8b42a3e618b475d/html5/thumbnails/37.jpg)
States over Time
Value as State
Reference to Identity
Identity over Time
![Page 38: (first '(Clojure.))](https://reader033.vdocuments.net/reader033/viewer/2022060111/5564af3ad8b42a3e618b475d/html5/thumbnails/38.jpg)
Atoms(def item-counter (atom 0))
(defn next-item [] (str "item-" (swap! item-counter inc)))
(next-item)=> "item-1"(next-item)=> "item-2"...
![Page 39: (first '(Clojure.))](https://reader033.vdocuments.net/reader033/viewer/2022060111/5564af3ad8b42a3e618b475d/html5/thumbnails/39.jpg)
Refs
(def item1 (ref {:a "foo"}))(def item2 (ref {:a "bar"}))
(let [v1 (:a @item1) v2 (:a @item2)] (dosync (alter item1 assoc :a v2) (alter item2 assoc :a v1)))
![Page 40: (first '(Clojure.))](https://reader033.vdocuments.net/reader033/viewer/2022060111/5564af3ad8b42a3e618b475d/html5/thumbnails/40.jpg)
Agents
(def info (agent {}))
(send info assoc :status :open)
; eventually,; (assoc info :status :open); is called
![Page 41: (first '(Clojure.))](https://reader033.vdocuments.net/reader033/viewer/2022060111/5564af3ad8b42a3e618b475d/html5/thumbnails/41.jpg)
Java Interop
![Page 42: (first '(Clojure.))](https://reader033.vdocuments.net/reader033/viewer/2022060111/5564af3ad8b42a3e618b475d/html5/thumbnails/42.jpg)
Working with Monsters
Can be shackled by parentheses,
even fed immutability,
but their nature is wild
![Page 43: (first '(Clojure.))](https://reader033.vdocuments.net/reader033/viewer/2022060111/5564af3ad8b42a3e618b475d/html5/thumbnails/43.jpg)
Parallel HTTP Fetches
(ns parallel-fetch (:import (java.io InputStream InputStreamReader BufferedReader) (java.net URL HttpURLConnection)))
![Page 44: (first '(Clojure.))](https://reader033.vdocuments.net/reader033/viewer/2022060111/5564af3ad8b42a3e618b475d/html5/thumbnails/44.jpg)
(defn get-url [url] (let [conn (doto (.openConnection (URL. url)) (.setRequestMethod "GET") (.connect))] (with-open [stream (BufferedReader. (InputStreamReader. (.getInputStream conn)))] (.toString (reduce #(.append %1 %2) (StringBuffer.) (line-seq stream))))))
![Page 45: (first '(Clojure.))](https://reader033.vdocuments.net/reader033/viewer/2022060111/5564af3ad8b42a3e618b475d/html5/thumbnails/45.jpg)
(defn get-urls [urls] (let [agents (doall (map #(agent %) urls))] (doseq [agent agents] (send-off agent get-url)) (apply await-for 5000 agents) (doall (map #(deref %) agents))))
(prn (get-urls ["http://erlang.org" "http://clojure.org/"]))
![Page 46: (first '(Clojure.))](https://reader033.vdocuments.net/reader033/viewer/2022060111/5564af3ad8b42a3e618b475d/html5/thumbnails/46.jpg)
Interface On Your Own Terms
![Page 47: (first '(Clojure.))](https://reader033.vdocuments.net/reader033/viewer/2022060111/5564af3ad8b42a3e618b475d/html5/thumbnails/47.jpg)
Idiom
(get-name root)
(get-attr link "href")
(get-child-elements div)
![Page 48: (first '(Clojure.))](https://reader033.vdocuments.net/reader033/viewer/2022060111/5564af3ad8b42a3e618b475d/html5/thumbnails/48.jpg)
Protocol
(defprotocol DomAccess (get-name [this]) (get-attr [this attr-name]) (get-child-elements [this]))
![Page 49: (first '(Clojure.))](https://reader033.vdocuments.net/reader033/viewer/2022060111/5564af3ad8b42a3e618b475d/html5/thumbnails/49.jpg)
Realization
(extend-type org.w3c.dom.Node DomAccess
(get-name [this] (.getNodeName this))
(get-attr [this attr-name] (if (.hasAttribute this attr-name) (.getAttribute this attr-name)))
(get-child-elements [this] (filter #(= (.getNodeType %1) Node/ELEMENT_NODE) (node-list (.getChildNodes this)))))
![Page 50: (first '(Clojure.))](https://reader033.vdocuments.net/reader033/viewer/2022060111/5564af3ad8b42a3e618b475d/html5/thumbnails/50.jpg)
Working with Clojure
![Page 51: (first '(Clojure.))](https://reader033.vdocuments.net/reader033/viewer/2022060111/5564af3ad8b42a3e618b475d/html5/thumbnails/51.jpg)
Leiningen
$ lein deps
$ lein compile
$ lein repl
$ lein uberjar
$ lein ring server-headless
![Page 52: (first '(Clojure.))](https://reader033.vdocuments.net/reader033/viewer/2022060111/5564af3ad8b42a3e618b475d/html5/thumbnails/52.jpg)
Editors
Vim: VimClojure
Emacs: Swank
IDEA: La Clojure
![Page 53: (first '(Clojure.))](https://reader033.vdocuments.net/reader033/viewer/2022060111/5564af3ad8b42a3e618b475d/html5/thumbnails/53.jpg)
More Info
<http://clojure.org/>
<http://clojure.org/cheatsheet>
<http://clojuredocs.org/>
<http://dev.clojure.org/display/community/Clojure+Success+Stories>
<http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hickey>
<http://www.infoq.com/presentations/Simple-Made-Easy>
![Page 54: (first '(Clojure.))](https://reader033.vdocuments.net/reader033/viewer/2022060111/5564af3ad8b42a3e618b475d/html5/thumbnails/54.jpg)
Have Fun!
![Page 55: (first '(Clojure.))](https://reader033.vdocuments.net/reader033/viewer/2022060111/5564af3ad8b42a3e618b475d/html5/thumbnails/55.jpg)
(thanks!)
![Page 56: (first '(Clojure.))](https://reader033.vdocuments.net/reader033/viewer/2022060111/5564af3ad8b42a3e618b475d/html5/thumbnails/56.jpg)
@niklasl
@valtechSweden
![Page 57: (first '(Clojure.))](https://reader033.vdocuments.net/reader033/viewer/2022060111/5564af3ad8b42a3e618b475d/html5/thumbnails/57.jpg)
Attribution
● Clojure Logo © Rich Hickey● Playing Ball● "Where the Wild Things Are" © Maurice Sendak● Parallel HTTP Fetches by Will Larson