Skip to content

Instantly share code, notes, and snippets.

@msgodf
Created March 19, 2015 16:18
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save msgodf/7e388776569cb8b83ca3 to your computer and use it in GitHub Desktop.
Save msgodf/7e388776569cb8b83ca3 to your computer and use it in GitHub Desktop.
Clojure intro

Intro to Clojure

Overview

First three hours of Clojure.

Small (~3 people) group, Java experience, some Javascript and other dynamic language experience - no prior Clojure knowledge is assumed.

What can you learn?

Something cool Something useful Something you already know

Things about Clojure

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.

The language

Data structures

sequences, vectors, maps, sets

[“a” 1 :b]

{:name “mark” :age 35}

#{:dog :cat :elephant}

Literals

strings, numbers, keywords

“tortoise” 1 :pineapple

Collection/sequence functions

Language contains lots of specific functions for working with sequences and collections

Accessing parts of collections and creating modified versions of those collections

All sequences

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]

Keyed sequences

get, get-in

(get [1 2 3] 0) => 1 (get-in {:a {:b 1}} [:a :b]) => 1

Maps

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

Sets

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}

Functions

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)

Higher order functions

Functions that take functions, ties into the sequence functions: map, filter, reduce

for comprehensions

Conditionals

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)

Immutability

let bindings, functions that take a value and return a value. Value types first.

(let [x 1] (+ x 1))

Mutability, managing state

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))

Laziness

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.

Namespaces

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]))

Working with Clojure

The REPL, interactive development.

Build, using libraries

Can run compiler stand-alone from command line using java Or use leiningen, a command line tool written in Clojure

Editors

Cursive (based on IntelliJ), Emacs, Vim, Sublime, lots of others

Useful third party libraries

compojure clj-http cheshire

Other topics

Testing, macros, Java interop, async

Resources/further reading:

CBT CGU JoC CP PC 4clojure try-clj clojure koans

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment