Introduction to Clojure

What is Clojure

Clojure is a …

functional

immutable by default

concurrency ready

dynamically typed

young (2007)

opinionated

LISP

for the JVM

(but also for JavaScript and .NET/CLR)

What is it used for?

Datomic

a time-aware, fully ACID database system

Puppet

PuppetDB and Trapperkeeper

Overtone

a live / collaborative music synthesis environment

sayHEY

a crypto messenger (developed by us) with a ClojureScript web client

Netflix, eBay, Daily Mail, …

Functional

lambda.png

Functional

Functions are first-class citizens

They can be passed around, composed, generated, …

Functional

For loop, imperative

var xs = [1, 2, 3];
var result = [];

for (var i = 0; i < xs.length; i++) {
  result.push(10 * xs[i]);
}

result // => [10, 20, 30]

Functional

Map, functional

var xs = [1, 2, 3];
var result = xs.map(function(x) { return 10 * x });

result // => [10, 20, 30]

In Clojure

(def xs [1 2 3])
(def result (map (fn [x] (* 10 x)) xs))

Functional

Programming with values instead of places

Rich Hickey – The Value of Values

Immutable by default

Values cannot be altered!

var things = ["frizzle", "scrooble", "yow"];
things[1] = "whoops";

things // => ["frizzle", "whoops", "yow"]

Immutable by default

var things = ["frizzle", "scrooble", "yow"];

frob(things);

things // => ?

Immutable by default

var init = 0;
var counter = init;
frob(init);
counter++;

init // => 0

Dynamically typed

hippie.jpg

Opinionated

Clojure values simplicity

Simple versus complex

Easy versus hard

Simple versus complex

simple-complex.png

objective

Simple versus complex

complex_vs_simple.png

Easy versus hard

albanian.png germany.png

relative / subjective

LISP

lisp.png

“The greatest single programming language ever designed.” – Alan Kay

“Lisp is a language for doing what you've been told is impossible.” – Kent Pitman

LISP

A program from ca. 1961:

DEFINE ((
(MEMBER (LAMBDA (A X) (COND ((NULL X) F)
     ((EQ A (CAR X)) T) (T (MEMBER A (CDR X))) )))
(UNION (LAMBDA (X Y) (COND ((NULL X) Y) ((MEMBER
     (CAR X) Y) (UNION (CDR X) Y)) (T (CONS (CAR X)
     (UNION (CDR X) Y))) )))
(INTERSECTION (LAMBDA (X Y) (COND ((NULL X) NIL)
     ((MEMBER (CAR X) Y) (CONS (CAR X) (INTERSECTION
     (CDR X) Y))) (T (INTERSECTION (CDR X) Y)) )))
))
INTERSECTION ((A1 A2 A3) (A1 A3 A5))
UNION ((X Y Z) (U V W X))

LISP

Lots of

Irritating

Superfluous

Parentheses

LISP

Anyone could learn Lisp in one day, except that if they already knew Fortran, it would take three days.

– Marvin Minsky

Syntax: Literals

Numbers

10 5/3 10.4

Strings

"This is a string"

"This is a
multi-line
string"

Keywords

:some-keyword

:and-a/namespaced-keyword

Symbols

a-symbol

a-namespaced/symbol

Syntax: Literals

Vectors

["one" :two 3]

Lists

(1 2 3 4 5)

(frob "zork" (twiddle 10 18))

Maps

{:foo 1 :bar 2}

Sets

#{1 2 3}

Function application

frob_numbers(1, 2, 3);

… becomes …

(frob-numbers 1 2 3)
  • move opening parenthesis to the left
  • remove line-noise

Arithmetic

It's just function application!

10 + 9 + 4 * (5 - 3)

… becomes …

(+ 10 9 (* 4 (- 5 3)))

No special precedence rules!

Interactive Development

REPL = Read-Eval-Print-Loop

repl.png

Explore your code interactively

Interactive Development

Custom functions

A function that squares a number

(fn [x] (* x x))

Applying it

((fn [x] (* x x)) 10) ; => 100

Naming Things

(def square 
  (fn [x] (* x x)))

(square 10) ; => 100

(defn square [x]
  (* x x))

(def almost-pi (/ 22 7))

Macros

Lisp is a programmable programming language.

– John Foderaro

Macros

macros.png

Homoiconicity

Code is Data

yinyang.png

Data is Code

Primacy of Data

It is better to have 100 functions operate on one data structure than 10 functions on 10 data structures.

– Alan J. Perlis

Concurrency

What's the problem with concurrency?

Race conditions!

var xs = [1, 2, 3];

               Thread A                   |     Thread B
------------------------------------------+------------------
                                          |
print("summing " + xs);                   |
var sum = 0;                              |
                                          |
for (var i = 0; i < xs.length; i++) {     |
  sum += xs[i];                           |    xs[2] = 5;
}                                         |
                                          |
print(sum); // might print 6 or 8

Possible remedies

Defensive copying

var xs = [1, 2, 3];
var ys = xs.slice();
xs[2]  = 5;
xs // => [1, 2, 5];
ys // => [1, 2, 3];

Drawbacks

  • Lots of copying
  • Easy to forget

Possible remedies

Locking

synchronized(xs, function() {
  // sum xs
});

Drawbacks

  • Blocks both readers and writers
  • May easily be too coarse grained
  • Possibility of dead locking
  • Leaks into user code

Clojure's concurrency model

Managed references

Immutable values

Example

(def xs (atom [1 2 3]))

            Thread A           |        Thread B
-------------------------------+-----------------------
(let [cxs (deref xs)]          |
  (println "summing" cxs)      |  (swap! xs assoc 2 5)
  (println (reduce + cxs)))    |
                               |
;; this will always print 6

For the JVM

Write once, run away

For the JVM

Tight interop with Java

Build on existing library ecosystem

Profit from VM optimizations

Run (almost) anywhere

Slow startup times

Memory hungry by default

Interop

Call methods

Instantiate objects

Reify or implement interfaces

Clojure types implement common interfaces

e.g. Clojure functions are java.lang.Runnable

Live demo

Ring

A modular HTTP server abstraction, similar to Rack or WSGI

A ring application is a regular Clojure function

It takes a request map as its argument

{:request-method :get
 :server-host "localhost"
 :server-port 8080
 :uri "/hello"}

And it returns a response map

{:status 200
 :body "Hello, world!"}

Tools

Leiningen

Cursive for IntelliJ

Counterclockwise for Eclipse

Cider for Emacs

VimClojure

Light Table

Literature

Fogus / Houser: The Joy Of Clojure. Thinking the Clojure Way.

Halloway / Bedra: Programming Clojure.

Sierra / VanderHart: ClojureScript. Up and Running.

Interactive tutorials

Useful URLs

Talks

The end

Thank you!

/

Moritz Heidkamp - Introduction to Clojure