Cracking clojure

3,632 views

Published on

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!

Published in: Business
1 Comment
12 Likes
Statistics
Notes
No Downloads
Views
Total views
3,632
On SlideShare
0
From Embeds
0
Number of Embeds
90
Actions
Shares
0
Downloads
126
Comments
1
Likes
12
Embeds 0
No embeds

No notes for slide

Cracking clojure

  1. 1. Cracking ClojureAlex MillerRevelytix
  2. 2. 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
  3. 3. It looks like this... (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)) 3
  4. 4. Primitives 4
  5. 5. Collections 5
  6. 6. Sequences 6
  7. 7. Sequences 6
  8. 8. Functions 7
  9. 9. Functions 7
  10. 10. Functions 7
  11. 11. Compiler 8
  12. 12. Casting spells 9
  13. 13. Creating functions 10
  14. 14. Creating functions 10
  15. 15. Creating functions 10
  16. 16. Creating functions 10
  17. 17. Creating functions 10
  18. 18. An example... 11
  19. 19. map 12
  20. 20. Sequence of lines 13
  21. 21. Sequence of files 14
  22. 22. Sequence of files 14
  23. 23. Sequence functions 15
  24. 24. You 16
  25. 25. Lazy sequences 17
  26. 26. 18
  27. 27. 18
  28. 28. Power 19
  29. 29. Objects 20
  30. 30. Maps as cheap objects 21
  31. 31. Records 22
  32. 32. Javapackage domain; int result = 1; result = prime * result + Float.floatToIntBits(alcohol);public class Beer { result = prime * result + ((beer == null) ? 0 : beer.hashCode()); private String beer; result = prime * result + ((brewery == null) ? 0 : private String brewery; brewery.hashCode()); private float alcohol; result = prime * result + ibu; private int ibu; return result; } public Beer(String beer, String brewery, float alcohol, int ibu) { super(); @Override this.beer = beer; public boolean equals(Object obj) { this.brewery = brewery; if (this == obj) this.alcohol = alcohol; return true; this.ibu = ibu; if (obj == null) } return false; if (getClass() != obj.getClass()) public String getBeer() { return false; return beer; Beer other = (Beer) obj; } if (Float.floatToIntBits(alcohol) != Float public String getBrewery() { .floatToIntBits(other.alcohol)) return brewery; return false; } if (beer == null) { public float getAlcohol() { if (other.beer != null) return alcohol; return false; } } else if (!beer.equals(other.beer)) public int getIbu() { return false; return ibu; if (brewery == null) { } if (other.brewery != null) public void setBeer(String beer) { return false; this.beer = beer; } else if (!brewery.equals(other.brewery)) } return false; public void setBrewery(String brewery) { if (ibu != other.ibu) this.brewery = brewery; return false; } return true; public void setAlcohol(float alcohol) { } this.alcohol = alcohol; } @Override public void setIbu(int ibu) { public String toString() { this.ibu = ibu; return "Beer [beer=" + beer + ", brewery=" + brewery + ", } alcohol=" + alcohol + ", ibu=" + ibu + "]"; } @Override } public int hashCode() { final int prime = 31; 23
  33. 33. Javapackage domain; int result = 1; result = prime * result + Float.floatToIntBits(alcohol);public class Beer { result = prime * result + ((beer == null) ? 0 : beer.hashCode()); private String beer; result = prime * result + ((brewery == null) ? 0 : private String brewery; brewery.hashCode()); private float alcohol; Fields and types result = prime * result + ibu; private int ibu; } return result; Hashing public Beer(String beer, String brewery, float alcohol, int ibu) { super(); @Override this.beer = beer; public boolean equals(Object obj) { this.brewery = brewery; this.alcohol = alcohol; Construction if (this == obj) return true; Equality this.ibu = ibu; if (obj == null) } return false; if (getClass() != obj.getClass()) public String getBeer() { return false; return beer; Beer other = (Beer) obj; } if (Float.floatToIntBits(alcohol) != Float public String getBrewery() { .floatToIntBits(other.alcohol)) return brewery; return false; } public float getAlcohol() { Getters if (beer == null) { if (other.beer != null) return alcohol; return false; } } else if (!beer.equals(other.beer)) public int getIbu() { return false; return ibu; if (brewery == null) { } if (other.brewery != null) public void setBeer(String beer) { return false; this.beer = beer; } else if (!brewery.equals(other.brewery)) } return false; public void setBrewery(String brewery) { if (ibu != other.ibu) this.brewery = brewery; return false; } return true; public void setAlcohol(float alcohol) { this.alcohol = alcohol; Setters } } @Override public void setIbu(int ibu) { public String toString() { this.ibu = ibu; return "Beer [beer=" + beer + ", brewery=" + brewery + ", } alcohol=" + alcohol + ", ibu=" + ibu + "]"; Printing } @Override } public int hashCode() { final int prime = 31; 23
  34. 34. Data interfaces 24
  35. 35. Data interfaces 24
  36. 36. Data interfaces 25
  37. 37. Data - Clojure vs Java 26
  38. 38. Data - Clojure vs Java 26
  39. 39. Polymorphism 27
  40. 40. Generic access FTW 28
  41. 41. Multimethods 29
  42. 42. Multimethod dispatch 30
  43. 43. Protocols 31
  44. 44. State 32
  45. 45. Atoms 33
  46. 46. Refs 34
  47. 47. Agents 35
  48. 48. Destructuring 36
  49. 49. for comprehensions 37
  50. 50. for comprehensions 37
  51. 51. Macros 38
  52. 52. Macros 39
  53. 53. Review CONCURRENCY HOST DATA CODE 40
  54. 54. Review CONCURRENCY HOST DATA CODE primitives 40
  55. 55. Review CONCURRENCY HOST DATA CODE collections primitives 40
  56. 56. Review CONCURRENCY HOST sequences DATA CODE collections primitives 40
  57. 57. Review CONCURRENCY HOST laziness sequences DATA CODE collections primitives 40
  58. 58. Review CONCURRENCY HOST laziness sequences FP DATA CODE collections primitives 40
  59. 59. Review CONCURRENCY HOST laziness sequence library sequences FP DATA CODE collections primitives 40
  60. 60. Review CONCURRENCY HOST laziness sequence library sequences FP records types DATA CODE collections primitives 40
  61. 61. Review CONCURRENCY HOST laziness sequence library sequences multimethods FP protocols records types DATA CODE collections primitives 40
  62. 62. Review refs agentsatoms CONCURRENCY HOST state laziness sequence library sequences multimethods FP protocols records types DATA CODE collections primitives 40
  63. 63. Review refs agentsatoms CONCURRENCY HOST state laziness sequence library sequences multimethods FP protocols records types DATA CODE collections primitives destructuring 40
  64. 64. Review refs agentsatoms CONCURRENCY HOST state laziness sequence library sequences multimethods FP protocols records types DATA macros CODE collections primitives destructuring 40
  65. 65. Review refs agentsatoms CONCURRENCY HOST state laziness sequence library sequences multimethods FP protocols records types DATA macros CODE metadata collections primitives destructuring transients 40
  66. 66. Review refs agentsatoms CONCURRENCY HOST state laziness sequence library sequences multimethods FP protocols records types DATA macros CODE metadata collections namespaces primitives destructuring transients 40
  67. 67. Review refs agentsatoms CONCURRENCY HOST state laziness sequence library sequences multimethods FP protocols records types recursion DATA macros CODE metadata collections namespaces primitives destructuring transients 40
  68. 68. Review refs agentsatoms CONCURRENCY HOST state Java libs laziness sequence library Java sequences interop multimethods FP protocols records types recursion DATA macros CODE metadata collections namespaces primitives destructuring transients 40
  69. 69. Review futures promises refs agentsatoms pmap CONCURRENCY HOST state Java libs laziness sequence library Java sequences interop multimethods FP protocols records types recursion DATA macros CODE metadata collections namespaces primitives destructuring transients 40
  70. 70. Conways Life Lifes rules: If alive and 2 or 3 neighbors Then stay alive Else die If dead and 3 neighbors Then come to life "Blinker" configuration Implementation courtesy of Christophe Grand http://clj-me.cgrand.net/2011/08/19/conways-game-of-life/ 41
  71. 71. 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

×