• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
JavaOne 2013 - Clojure for Java Developers
 

JavaOne 2013 - Clojure for Java Developers

on

  • 580 views

The fact that Clojure is a dialect of Lisp makes it feel completely alien to Java developers, and they miss the opportunity to learn this dynamic and functional programming language for the JVM. ...

The fact that Clojure is a dialect of Lisp makes it feel completely alien to Java developers, and they miss the opportunity to learn this dynamic and functional programming language for the JVM. Clojure’s focus on immutability makes it very useful for concurrency. This presentation introduces Clojure in a way that feels natural to Java developers. By seeing how well Clojure interoperates with Java, you will learn how to take advantage of this wonderful language and still use all the frameworks and features of the JVM.

Statistics

Views

Total Views
580
Views on SlideShare
580
Embed Views
0

Actions

Likes
0
Downloads
16
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    JavaOne 2013 - Clojure for Java Developers JavaOne 2013 - Clojure for Java Developers Presentation Transcript

    • for Java developers Clojure jan.kronquist@jayway.com onsdag 25 september 13
    • About me onsdag 25 september 13
    • About me 1986 - Basic onsdag 25 september 13
    • About me 1990 - 68K assembly 1986 - Basic onsdag 25 september 13
    • About me 1990 - 68K assembly1986 - Basic 1995 - OOP onsdag 25 september 13
    • 1997 - University About me 1990 - 68K assembly1986 - Basic 1995 - OOP onsdag 25 september 13
    • 1997 - University About me 1990 - 68K assembly1986 - Basic 2005 - IoC,Aspects, Mixins 1995 - OOP onsdag 25 september 13
    • 2008 - Functional 1997 - University About me 1990 - 68K assembly1986 - Basic 2005 - IoC,Aspects, Mixins 1995 - OOP onsdag 25 september 13
    • 2012 - Lisp & dynamic typing 2008 - Functional 1997 - University About me 1990 - 68K assembly1986 - Basic 2005 - IoC,Aspects, Mixins 1995 - OOP onsdag 25 september 13
    • This talk is not A comprehensive introduction to Clojure About idiomatic Clojure Another talk about functional programming onsdag 25 september 13
    • Killer apps onsdag 25 september 13
    • Killer apps Prismatic onsdag 25 september 13
    • Killer apps Prismatic onsdag 25 september 13
    • Killer apps Prismatic Datomic Storm ClojureScript onsdag 25 september 13
    • What is Clojure? Created 2007 by Rich Hickey Lisp Runs on JVM, CLR & JavaScript Design for concurrency onsdag 25 september 13
    • Clojure example (defn divisible? [n d] (== 0 (mod n d))) (defn divides [n] (partial divisible? n)) (declare primes) (defn prime? [n] (not (some (divides n) (take-while #(< % n) primes)))) (def primes (lazy-cat [2 3 5] (filter prime? (drop 7 (range))))) onsdag 25 september 13
    • Why Clojure? onsdag 25 september 13
    • Why Clojure? Lisp - Code as data & Syntactic abstraction onsdag 25 september 13
    • Why Clojure? Lisp - Code as data & Syntactic abstraction Functional - Declarative, Immutable onsdag 25 september 13
    • Why Clojure? Lisp - Code as data & Syntactic abstraction Functional - Declarative, Immutable Interactive development environment onsdag 25 september 13
    • Why Clojure? Lisp - Code as data & Syntactic abstraction Functional - Declarative, Immutable Interactive development environment Great eco-system - dynamic helps compatibility onsdag 25 september 13
    • Why Clojure? Lisp - Code as data & Syntactic abstraction Functional - Declarative, Immutable Interactive development environment Great eco-system - dynamic helps compatibility Wrapper-free Java access onsdag 25 september 13
    • Why Clojure? Lisp - Code as data & Syntactic abstraction Functional - Declarative, Immutable Interactive development environment Great eco-system - dynamic helps compatibility Wrapper-free Java access Less complexity onsdag 25 september 13
    • Common complaints onsdag 25 september 13
    • Common complaints Lisp looks weird onsdag 25 september 13
    • Common complaints Dynamic typing is scary Lisp looks weird onsdag 25 september 13
    • Common complaints Dynamic typing is scary Lisp looks weird Just a toy language onsdag 25 september 13
    • Common complaints Dynamic typing is scary Lisp looks weird Macros? Are you crazy? Just a toy language onsdag 25 september 13
    • Lispness onsdag 25 september 13
    • Clojure Atomic Data Types Arbitrary precision integers: 12345678987654 Doubles: 1.234 BigDecimals: 1.234M Ratios: 22/7 Strings: "fred" , Characters: a b c Symbols: fred ethel , Keywords: :fred :ethel Booleans: true false , Null: - nil Regex patterns #"a*b" Rich Hickey - Clojure for Java Programmers - http://www.youtube.com/watch?v=P76Vbsk_3J0 onsdag 25 september 13
    • JavaScript Data Structures Arrays [1, 2, 3] ["fred", "ethel", "lucy"] Objects {name: "Jan Kronquist", age: 37} onsdag 25 september 13
    • Clojure Data Structures Vectors [1, 2, 3] ["fred", "ethel", "lucy"] Maps {:name "Jan Kronquist", :age 37} move colon onsdag 25 september 13
    • Clojure Data Structures Vectors [1 2 3] ["fred" "ethel" "lucy"] Maps {:name "Jan Kronquist" :age 37} commas are whitespace! onsdag 25 september 13
    • Clojure Data Structures Vectors - indexed access [1 2 3] ["fred" "ethel" "lucy"] Maps {:name "Jan Kronquist" :age 37} Lists - singly linked (1 2 3 4 5) (fred ethel lucy) (list 1 2 3) Sets #{fred ethel lucy} onsdag 25 september 13
    • Demo in REPL user=> "hello" "hello" user=> 5 5 user=> [1 2 3] [1 2 3] user=> qwe java.lang.RuntimeException: Unable to resolve symbol: qwe user=> (def qwe "hello world") #'user/qwe user=> qwe "hello world" onsdag 25 september 13
    • "Hello world") The strangeness of Lisp println( onsdag 25 september 13
    • "Hello world") The strangeness of Lisp println( onsdag 25 september 13
    • "Hello world") The strangeness of Lisp println( (operator operand1 operand2 ...) Determines how the list is evaluated onsdag 25 september 13
    • (= (.toString (+ 1 2)) "3") Example evaluation (= (.toString (+ 1 2)) "3") onsdag 25 september 13
    • (= (.toString (+ 1 2)) "3") Example evaluation onsdag 25 september 13
    • (= (.toString (+ 1 2)) "3") Example evaluation (= (.toString 3) "3") onsdag 25 september 13
    • (= (.toString (+ 1 2)) "3") Example evaluation (= (.toString 3) "3") (= "3" "3") onsdag 25 september 13
    • (= (.toString (+ 1 2)) "3") Example evaluation (= (.toString 3) "3") (= "3" "3") true onsdag 25 september 13
    • onsdag 25 september 13
    • int i = 5; (def i 5) OR (let [i 5] ...) if (x > 5) { return y; } else { return z; } (if (> x 5) y z) x * y * z (* x y z) foo(x, y, z) (foo x y z) object.method(x, y) (.method object x y) public String sayHello(String x) { return "Hello " + x; } (defn sayHello [x] (str "Hello " x)) onsdag 25 september 13
    • int i = 5; (def i 5) OR (let [i 5] ...) if (x > 5) { return y; } else { return z; } (if (> x 5) y z) x * y * z (* x y z) foo(x, y, z) (foo x y z) object.method(x, y) (.method object x y) public String sayHello(String x) { return "Hello " + x; } (defn sayHello [x] (str "Hello " x)) onsdag 25 september 13
    • int i = 5; (def i 5) OR (let [i 5] ...) if (x > 5) { return y; } else { return z; } (if (> x 5) y z) x * y * z (* x y z) foo(x, y, z) (foo x y z) object.method(x, y) (.method object x y) public String sayHello(String x) { return "Hello " + x; } (defn sayHello [x] (str "Hello " x)) onsdag 25 september 13
    • int i = 5; (def i 5) OR (let [i 5] ...) if (x > 5) { return y; } else { return z; } (if (> x 5) y z) x * y * z (* x y z) foo(x, y, z) (foo x y z) object.method(x, y) (.method object x y) public String sayHello(String x) { return "Hello " + x; } (defn sayHello [x] (str "Hello " x)) onsdag 25 september 13
    • int i = 5; (def i 5) OR (let [i 5] ...) if (x > 5) { return y; } else { return z; } (if (> x 5) y z) x * y * z (* x y z) foo(x, y, z) (foo x y z) object.method(x, y) (.method object x y) public String sayHello(String x) { return "Hello " + x; } (defn sayHello [x] (str "Hello " x)) onsdag 25 september 13
    • int i = 5; (def i 5) OR (let [i 5] ...) if (x > 5) { return y; } else { return z; } (if (> x 5) y z) x * y * z (* x y z) foo(x, y, z) (foo x y z) object.method(x, y) (.method object x y) public String sayHello(String x) { return "Hello " + x; } (defn sayHello [x] (str "Hello " x)) onsdag 25 september 13
    • Java Quiz public static void main(String[] args) { int bang = 1; do while (bang>=1) System.out.print(" bang is "+ bang); while (bang>1); } onsdag 25 september 13
    • Macros onsdag 25 september 13
    • Working with Java classes (defn display [text] (let [frame (new JFrame "MyFrame")] (.add frame (new JLabel text)) (.setSize frame 300 200) (.setVisible frame true))) static void display(String text) { JFrame frame = new JFrame("MyFrame"); frame.add(new JLabel(text)); frame.setSize(300, 200); frame.setVisible(true); } onsdag 25 september 13
    • Working with Java classes (defn display [text] (let [frame (new JFrame "MyFrame")] (.add frame (new JLabel text)) (.setSize frame 300 200) (.setVisible frame true))) static void display(String text) { JFrame frame = new JFrame("MyFrame"); frame.add(new JLabel(text)); frame.setSize(300, 200); frame.setVisible(true); } (display "Hello World") onsdag 25 september 13
    • Working with Java classes (defn display [text] (let [frame (new JFrame "MyFrame")] (.add frame (new JLabel text)) (.setSize frame 300 200) (.setVisible frame true))) static void display(String text) { JFrame frame = new JFrame("MyFrame"); frame.add(new JLabel(text)); frame.setSize(300, 200); frame.setVisible(true); } a pattern! onsdag 25 september 13
    • static void display(String text) { JFrame frame = new JFrame("MyFrame"); with (frame) { .add(new JLabel(text)); .setSize(300, 200); .setVisible(true); } } Working with Java classes (defn display [text] (let [frame (new JFrame "MyFrame")] (.add frame (new JLabel text)) (.setSize frame 300 200) (.setVisible frame true))) onsdag 25 september 13
    • (defn display [text] (let [frame (new JFrame "MyFrame")] (doto frame (.add (new JLabel text)) (.setSize 300 200) (.setVisible true)))) Working with Java classes static void display(String text) { JFrame frame = new JFrame("MyFrame"); with (frame) { .add(new JLabel(text)); .setSize(300, 200); .setVisible(true); } } onsdag 25 september 13
    • (defn display [text] (doto (new JFrame "MyFrame") (.add (new JLabel text)) (.setSize 300 200) (.setVisible true))) Working with Java classes static void display(String text) { JFrame frame = new JFrame("MyFrame"); frame.add(new JLabel(text)); frame.setSize(300, 200); frame.setVisible(true); } onsdag 25 september 13
    • (defn display [text] (doto (new JFrame "MyFrame") (.add (new JLabel text)) (.setSize 300 200) (.setVisible true))) Working with Java classes static void display(String text) { JFrame frame = new JFrame("MyFrame"); frame.add(new JLabel(text)); frame.setSize(300, 200); frame.setVisible(true); } Ok, nice, but in practice you would never want something like this? onsdag 25 september 13
    • static void write(String fileName, String text) throws IOException { try (Writer writer = new FileWriter(fileName)) { writer.write(text); } } Trust me, you want macros onsdag 25 september 13
    • static void write(String fileName, String text) throws IOException { try (Writer writer = new FileWriter(fileName)) { writer.write(text); } } Trust me, you want macros (defn write [fileName text] (with-open [writer (new FileWriter fileName)] (.write writer text))) onsdag 25 september 13
    • Toy? onsdag 25 september 13
    • Structure in Modules - package Abstraction - interface Implementation - class onsdag 25 september 13
    • Structure in Modules - package Abstraction - interface Implementation - class Problems mutable state? static methods? inheritance? constants? onsdag 25 september 13
    • Structure in Modules namespace - first-class, dynamic, import, aliasing Abstraction defprotocol - can be added later Implementation defrecord - immutable, equals, hashcode, etc deftype - may mutate, only user functionilty reify - singleton gen-class & proxy - for Java interop onsdag 25 september 13
    • Records - creating (ns my.namespace) (defrecord Person [firstName lastName]) (new Person "Jan" "Kronquist") onsdag 25 september 13
    • Records - creating ; #my.namespace.Person{:firstName "Jan", :lastName "Kronquist"} (ns my.namespace) (defrecord Person [firstName lastName]) (new Person "Jan" "Kronquist") onsdag 25 september 13
    • Records - field access ; #my.namespace.Person{:firstName "Jan", :lastName "Kronquist"} (ns my.namespace) (defrecord Person [firstName lastName]) (new Person "Jan" "Kronquist") (def person (new Person "Jan" "Kronquist")) (.firstName person) onsdag 25 september 13
    • Records - field access ; #my.namespace.Person{:firstName "Jan", :lastName "Kronquist"} (ns my.namespace) (defrecord Person [firstName lastName]) (new Person "Jan" "Kronquist") (def person (new Person "Jan" "Kronquist")) (.firstName person) ; "Jan" onsdag 25 september 13
    • Records - named parameters ; #my.namespace.Person{:firstName "Jan", :lastName "Kronquist"} (ns my.namespace) (defrecord Person [firstName lastName]) (new Person "Jan" "Kronquist") (def person (new Person "Jan" "Kronquist")) (.firstName person) ; "Jan" (map->Person {:lastName "Kronquist" :firstName "Jan"}) onsdag 25 september 13
    • Records - named parameters ; #my.namespace.Person{:firstName "Jan", :lastName "Kronquist"} (ns my.namespace) (defrecord Person [firstName lastName]) (new Person "Jan" "Kronquist") (def person (new Person "Jan" "Kronquist")) (.firstName person) ; "Jan" (map->Person {:lastName "Kronquist" :firstName "Jan"}) ; #my.namespace.Person{:firstName "Jan", :lastName "Kronquist"} onsdag 25 september 13
    • Records and protocols (defprotocol Nameable (getName [this])) onsdag 25 september 13
    • Records and protocols (defprotocol Nameable (getName [this])) (defrecord Person [firstName lastName] Nameable (getName [this] (str firstName " " lastName))) (getName (new Person "Jan" "Kronquist")) ; "Jan Kronquist" Person class implements Nameable interface onsdag 25 september 13
    • Records and protocols (defprotocol Nameable (getName [this])) (defrecord Person [firstName lastName]) (extend-protocol Nameable Person (getName [this] (str (.firstName this) " " (.lastName this)))) (getName (new Person "Jan" "Kronquist")) ; "Jan Kronquist" (defrecord Person [firstName lastName] Nameable (getName [this] (str firstName " " lastName))) (getName (new Person "Jan" "Kronquist")) ; "Jan Kronquist" Person class implements Nameable interface Person extended by Nameable after definition! onsdag 25 september 13
    • Records and protocols (defprotocol Nameable (getName [this])) (defrecord Person [firstName lastName]) (extend-protocol Nameable Person (getName [this] (str (.firstName this) " " (.lastName this)))) (getName (new Person "Jan" "Kronquist")) ; "Jan Kronquist" (defrecord Person [firstName lastName] Nameable (getName [this] (str firstName " " lastName))) (.getName (new Person "Jan" "Kronquist")) ; "Jan Kronquist" Method getName exists on Person class onsdag 25 september 13
    • Records and protocols (defprotocol Nameable (getName [this])) (defrecord Person [firstName lastName]) (extend-protocol Nameable Person (getName [this] (str (.firstName this) " " (.lastName this)))) (.getName (new Person "Jan" "Kronquist")) ; IllegalArgumentException No matching field found: getName (defrecord Person [firstName lastName] Nameable (getName [this] (str firstName " " lastName))) (.getName (new Person "Jan" "Kronquist")) ; "Jan Kronquist" Method getName exists on Person class But not in this case! onsdag 25 september 13
    • Editors and IDEs? Eclipse - Counterclockwise IntelliJ - La Clojure Light Table Sublime Textmate Emacs onsdag 25 september 13
    • Eclipse Counterclockwise ✓Restrictive formatting ✓Paren coloring ✓Typing suggestions ✓Being Eclipse https://code.google.com/p/counterclockwise/ onsdag 25 september 13
    • Light table ✓Cool ✓Insta-REPL http://www.lighttable.com/ onsdag 25 september 13
    • Sublime ✓General purpose editor ✓Typing suggestions http://www.sublimetext.com/ onsdag 25 september 13
    • Repositories Maven style Maven central http://clojars.org/repo onsdag 25 september 13
    • Build tools Maven plugin Gradle plugin Leiningen onsdag 25 september 13
    • Leiningen (defproject myproject "0.5.0-SNAPSHOT" :description "A project for doing things." :url "http://github.com/foo/bar" :dependencies [[org.clojure/clojure "1.5.1"] [ring/ring-core "1.2.0 "]] :plugins [[lein-ring "0.4.5"]]) onsdag 25 september 13
    • Dynamic typing onsdag 25 september 13
    • Dynamic typing? Robert Smallshire - The Unreasonable Effectiveness of Dynamic Typing for Practical Programs onsdag 25 september 13
    • Dynamic typing is scary Compiler won’t find errors Limited tool support Performance? onsdag 25 september 13
    • What made me think twice Web server onsdag 25 september 13
    • What made me think twice Web server onsdag 25 september 13
    • Clojure makes dynamic typing ok REPL Immutable data structure Pure functions Automated tests onsdag 25 september 13
    • Dynamic typing and performance? Clojure is compiled to bytecode Generally good enough! onsdag 25 september 13
    • Dynamic typing and performance? Clojure is compiled to bytecode Generally good enough! (defn len [^String x] (.length x)) onsdag 25 september 13
    • Studies Stefan Hanenberg & Lutz Prechelt Dynamic is more productive No difference in reliability Robert Smallshire - 2 % defects are type errors (GitHub) onsdag 25 september 13
    • Conclusion onsdag 25 september 13
    • Macros? Are you crazy? Dynamic typing is scary Convinced? Lisp looks weird Just a toy language onsdag 25 september 13
    • Macros? Are you crazy? Dynamic typing is usable Convinced? Lisp looks weird Just a toy language REPL Immutable data structure Pure functions Automated tests onsdag 25 september 13
    • Macros? Are you crazy? Lisp is consistent Dynamic typing is usable Convinced? Just a toy language REPL Immutable data structure Pure functions Automated tests (operation operand1 operand2 ...) onsdag 25 september 13
    • Macros? Are you crazy? Lisp is consistent Dynamic typing is usable Convinced? REPL Immutable data structure Pure functions Automated tests Interesting language (operation operand1 operand2 ...) Namespaces Prototcols Records onsdag 25 september 13
    • Macros? Are you crazy? Lisp is consistent Dynamic typing is usable Convinced? REPL Immutable data structure Pure functions Automated tests Interesting language (operation operand1 operand2 ...) Lazy seqs STM Functional Namespaces Prototcols Records onsdag 25 september 13
    • Macros? Maybe....... Lisp is consistent Dynamic typing is usable Convinced? REPL Immutable data structure Pure functions Automated tests Interesting language (operation operand1 operand2 ...) Lazy seqs STM Functional Namespaces Prototcols Records try (Writer writer = new FileWriter(fileName)) writer.write(text); } onsdag 25 september 13
    • Macros? Maybe....... Lisp is consistent Dynamic typing is usable Convinced? REPL Immutable data structure Pure functions Automated tests Interesting language (operation operand1 operand2 ...) Lazy seqs STM Functional Namespaces Prototcols Records try (Writer writer = new FileWriter(fileName)) writer.write(text); } DSL Reuse Structure onsdag 25 september 13
    • Further resources http://clojure.org/ http://tryclj.com/ http://www.4clojure.com http://clojure-doc.org/ onsdag 25 september 13
    • Questions? onsdag 25 september 13