Cracking clojure

Post on 06-May-2015

2.714 views 1 download

description

Maybe you've heard of Clojure, one of those new-fangled JVM languages. How does anybody get any work done in a language like that? What's up with all those parentheses?If you're coming from Java and OOP, Clojure can indeed feel disorienting. In this talk we'll demystify the basics of Clojure and dissect the source of its power. Functional programming is on the rise and Clojure is indeed a functional language, but we'll learn the real secret sauce that makes cooking with Clojure fun.We'll look at how to translate concepts you know in Java (like domain objects, interfaces, collections, and concurrency) into their natural Clojure equivalents. And more importantly, we'll learn how these components interact to make Clojure a beautiful language for building abstractions.No prior knowledge of Clojure or functional programming is assumed... Clojure novices welcome!

Transcript of Cracking clojure

Cracking ClojureAlex MillerRevelytix

Clojure• A Lisp on the JVM (also ClojureScript on JavaScript)

• Dynamic (types, code, etc)• Functional language• Compiled (there is no interpreter)• Immutability and state management• Code is data • REPL - Read / Eval / Print / Loop• Interactive development

2

It looks like this...

3

(defn neighbors [[x y]] (for [dx [-1 0 1] dy (if (zero? dx) [-1 1] [-1 0 1])] [(+ dx x) (+ dy y)]))

(defn live [n alive?] (or (= n 3) (and (= n 2) alive?)))

(defn step [world] (set (for [[cell n] (frequencies (mapcat neighbors world)) :when (live n (world cell))] cell)))

(defn life [initial-world] (iterate step initial-world))

Primitives

4

Collections

5

Sequences

6

Sequences

6

Functions

7

Functions

7

Functions

7

Compiler

8

Casting spells

9

Creating functions

10

Creating functions

10

Creating functions

10

Creating functions

10

Creating functions

10

An example...

11

map

12

Sequence of lines

13

Sequence of files

14

Sequence of files

14

Sequence functions

15

You

16

Lazy sequences

17

18

18

Power

19

Objects

20

Maps as cheap objects

21

Records

22

Java

23

package domain;

public class Beer { private String beer; private String brewery; private float alcohol; private int ibu; public Beer(String beer, String brewery, float alcohol, int ibu) { super(); this.beer = beer; this.brewery = brewery; this.alcohol = alcohol; this.ibu = ibu; }

public String getBeer() { return beer; } public String getBrewery() { return brewery; } public float getAlcohol() { return alcohol; } public int getIbu() { return ibu; } public void setBeer(String beer) { this.beer = beer; } public void setBrewery(String brewery) { this.brewery = brewery; } public void setAlcohol(float alcohol) { this.alcohol = alcohol; } public void setIbu(int ibu) { this.ibu = ibu; }

@Override public int hashCode() { final int prime = 31;

int result = 1; result = prime * result + Float.floatToIntBits(alcohol); result = prime * result + ((beer == null) ? 0 : beer.hashCode()); result = prime * result + ((brewery == null) ? 0 : brewery.hashCode()); result = prime * result + ibu; return result; }

@Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Beer other = (Beer) obj; if (Float.floatToIntBits(alcohol) != Float .floatToIntBits(other.alcohol)) return false; if (beer == null) { if (other.beer != null) return false; } else if (!beer.equals(other.beer)) return false; if (brewery == null) { if (other.brewery != null) return false; } else if (!brewery.equals(other.brewery)) return false; if (ibu != other.ibu) return false; return true; }

@Override public String toString() { return "Beer [beer=" + beer + ", brewery=" + brewery + ", alcohol=" + alcohol + ", ibu=" + ibu + "]"; }}

Java

23

package domain;

public class Beer { private String beer; private String brewery; private float alcohol; private int ibu; public Beer(String beer, String brewery, float alcohol, int ibu) { super(); this.beer = beer; this.brewery = brewery; this.alcohol = alcohol; this.ibu = ibu; }

public String getBeer() { return beer; } public String getBrewery() { return brewery; } public float getAlcohol() { return alcohol; } public int getIbu() { return ibu; } public void setBeer(String beer) { this.beer = beer; } public void setBrewery(String brewery) { this.brewery = brewery; } public void setAlcohol(float alcohol) { this.alcohol = alcohol; } public void setIbu(int ibu) { this.ibu = ibu; }

@Override public int hashCode() { final int prime = 31;

int result = 1; result = prime * result + Float.floatToIntBits(alcohol); result = prime * result + ((beer == null) ? 0 : beer.hashCode()); result = prime * result + ((brewery == null) ? 0 : brewery.hashCode()); result = prime * result + ibu; return result; }

@Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Beer other = (Beer) obj; if (Float.floatToIntBits(alcohol) != Float .floatToIntBits(other.alcohol)) return false; if (beer == null) { if (other.beer != null) return false; } else if (!beer.equals(other.beer)) return false; if (brewery == null) { if (other.brewery != null) return false; } else if (!brewery.equals(other.brewery)) return false; if (ibu != other.ibu) return false; return true; }

@Override public String toString() { return "Beer [beer=" + beer + ", brewery=" + brewery + ", alcohol=" + alcohol + ", ibu=" + ibu + "]"; }}

Fields and types

Construction

Getters

Setters

Hashing

Equality

Printing

Data interfaces

24

Data interfaces

24

Data interfaces

25

Data - Clojure vs Java

26

Data - Clojure vs Java

26

Polymorphism

27

Generic access FTW

28

Multimethods

29

Multimethod dispatch

30

Protocols

31

State

32

Atoms

33

Refs

34

Agents

35

Destructuring

36

for comprehensions

37

for comprehensions

37

Macros

38

Macros

39

Review

40

DATA CODE

HOSTCONCURRENCY

Review

40

DATA CODE

HOSTCONCURRENCY

primitives

Review

40

DATA CODE

HOSTCONCURRENCY

primitives

collections

Review

40

DATA CODE

HOSTCONCURRENCY

sequences

primitives

collections

Review

40

DATA CODE

HOSTCONCURRENCY

sequences

laziness

primitives

collections

Review

40

DATA CODE

HOSTCONCURRENCY

sequences

laziness

FP

primitives

collections

Review

40

DATA CODE

HOSTCONCURRENCY

sequences

lazinesssequence library

FP

primitives

collections

Review

40

DATA CODE

HOSTCONCURRENCY

recordstypes

sequences

lazinesssequence library

FP

primitives

collections

Review

40

DATA CODE

HOSTCONCURRENCY

recordstypes

sequences

lazinesssequence library

FP

primitives

collections

multimethodsprotocols

Review

40

DATA CODE

HOSTCONCURRENCY

recordstypes

atoms

state

refs agents

sequences

lazinesssequence library

FP

primitives

collections

multimethodsprotocols

Review

40

DATA CODE

HOSTCONCURRENCY

recordstypes

atoms

state

refs agents

sequences

lazinesssequence library

FP

primitives

collections

destructuring

multimethodsprotocols

Review

40

DATA CODE

HOSTCONCURRENCY

recordstypes

atoms

state

refs agents

sequences

lazinesssequence library

FP

macros

primitives

collections

destructuring

multimethodsprotocols

Review

40

DATA CODE

HOSTCONCURRENCY

metadata

recordstypes

atoms

state

refs agents

sequences

lazinesssequence library

FP

macros

primitives

collections

transientsdestructuring

multimethodsprotocols

Review

40

DATA CODE

HOSTCONCURRENCY

metadata

recordstypes

atoms

state

refs agents

sequences

lazinesssequence library

FP

macros

primitives

collections

transientsdestructuring

namespaces

multimethodsprotocols

Review

40

DATA CODE

HOSTCONCURRENCY

metadata

recordstypes

atoms

state

refs agents

sequences

lazinesssequence library

FP

macros

primitives

collections

transientsdestructuring

namespaces

recursion

multimethodsprotocols

Review

40

DATA CODE

HOSTCONCURRENCY

metadata

recordstypes

atoms

state

refs agents

sequences

lazinesssequence library

FP

macros

primitives

collections

transientsdestructuring

namespaces

recursion

multimethodsprotocols

Java interop

Java libs

Review

40

DATA CODE

HOSTCONCURRENCY

metadata

recordstypes

atoms

state

refs agents

sequences

laziness

futures promises

pmap

sequence library

FP

macros

primitives

collections

transientsdestructuring

namespaces

recursion

multimethodsprotocols

Java interop

Java libs

Conway's Life

41

Implementation courtesy of Christophe Grandhttp://clj-me.cgrand.net/2011/08/19/conways-game-of-life/

"Blinker" configuration

Life's rules: If alive and 2 or 3 neighbors Then stay alive Else die If dead and 3 neighbors Then come to life

Thanks!

• Twitter: @puredanger• Blog: http://tech.puredanger.com• Work: http://revelytix.com• My conferences

– Strange Loop - http://thestrangeloop.com– Clojure/West - http://clojurewest.com

If you want to pair on Clojure during Devoxx, ping me on Twitter!

43