First three hours of Clojure.
Small (~3 people) group, Java experience, some Javascript and other dynamic language experience - no prior Clojure knowledge is assumed.
Something cool Something useful Something you already know
It’s a Lisp - Programs are composed of s-expressions
But with a richer syntax than most Lisps - literal syntax for vectors and maps.
Implementations/variants for CLR (.net) and JS - but most mature is the JVM implementation. Not all equivalent.
Dynamically typed.
JVM variant written in a mixture of Java and Clojure - Clojure code is compiled (either at compile time or at runtime) to JVM bytecode.
sequences, vectors, maps, sets
[“a” 1 :b]
{:name “mark” :age 35}
#{:dog :cat :elephant}
strings, numbers, keywords
“tortoise” 1 :pineapple
Language contains lots of specific functions for working with sequences and collections
Accessing parts of collections and creating modified versions of those collections
first, last, rest, next, drop, take
(first [1 2 3]) => 1 (last [1 2 3]) => 3 (rest [1 2 3]) => [2 3] (next [1 2 3]) => [2 3] (drop 2 [1 2 3]) => [3] (take 2 [1 2 3]) => [1 2]
get, get-in
(get [1 2 3] 0) => 1 (get-in {:a {:b 1}} [:a :b]) => 1
assoc, dissoc, merge, select-keys
(assoc {:a 1} :b 2) => {:a 1 :b 2} (dissoc {:a 1 :b 2} :a) => {:b 2} (select-keys {:a 1 :b 2 :c 3} [:a :b]) => {:a 1 :b 2}
into
conj, disj, clojure.set/difference, clojure.set/union
(conj #{1 2} 3) => #{1 2 3} (conj #{1 2} 2) => #{1 2} (disj #{1 2 3} 3) => #{1 2} (clojure.set/difference #{1 2 3} #{2 3 4}) => #{2 3} (clojure.set/union #{1 2} #{2 3}) => #{1 2 3}
fn, arguments supplied in vector, implicit return, reader syntax #()
(fn [x] (+ x 1))
How to call functions?
((fn [x] (+ x 1)) 2) => 3
#(+ %1 1)
Functions that take functions, ties into the sequence functions: map, filter, reduce
for comprehensions
if, case, cond, when
(if p 1 0)
(case p 0 :a 1 :b :else :c)
(cond (= p 0) :a (= p 1) :b :else :c)
(when p 1)
let bindings, functions that take a value and return a value. Value types first.
(let [x 1] (+ x 1))
atoms - atomic reference
(let [x (atom 1)] (deref x))
(let [x (atom 1)] @x)
(let [x (atom 1)] (reset! x 2))
(let [x (atom 1)] (swap! x inc))
- Opt-in purity -> Clojure is an impure functional language, functions can have side-effects
(do (launch-the-missiles) (feed-the-cat))
sequences. For example, iterate, range: functions that return lazy sequences
(iterate inc 0) (range 10)
How to force eager evaluation of a sequence?
Can be necessary if depending on side-effects.
Organising code, using dependencies
(ns your-name.start)
(ns your-name.start (:require [your-name.util]))
(ns your-name.start (:require [your-name.util :as util]))
(ns your-name.start (:require [your-name.util :refer [implode]))
The REPL, interactive development.
Can run compiler stand-alone from command line using java Or use leiningen, a command line tool written in Clojure
Cursive (based on IntelliJ), Emacs, Vim, Sublime, lots of others
compojure clj-http cheshire
Testing, macros, Java interop, async
CBT CGU JoC CP PC 4clojure try-clj clojure koans