Top Banner
Copyright 2007-2010 Relevance, Inc. This presentation is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License. See http://creativecommons.org/licenses/by-nc-sa/3.0/us/ Stuart Halloway [email protected] @stuarthalloway Clojure-Java Interop onsdag, 2010 november 03
122

Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

Jul 31, 2018

Download

Documents

doannhu
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

Copyright 2007-2010 Relevance, Inc. This presentation is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License.

See http://creativecommons.org/licenses/by-nc-sa/3.0/us/

Stuart [email protected]@stuarthalloway

Clojure-JavaInterop

onsdag, 2010 november 03

Page 2: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

the plan

2

syntax

plumbing

Clojure calling Java

objects, Clojure style

Java calling Clojure

design principles

simplicity

direct access

bonus example

onsdag, 2010 november 03

Page 3: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

syntax

3

onsdag, 2010 november 03

Page 4: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

atomic data typestype example java equivalentstring "foo" String

character \f Character

regex #"fo*" Pattern

integer 42 Long

a.r. integer 42N BigInteger

double 3.14159 Double

a.p. double 3.14159M BigDecimal

boolean true Boolean

nil nil null

ratio 22/7 N/A

symbol foo, + N/A

keyword :foo, ::foo N/A4

onsdag, 2010 november 03

Page 5: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

data literals

type properties example

list singly-linked,insert at front (1 2 3)

vector indexed,insert at rear [1 2 3]

map key/value{:a 100 :b 90}

set key #{:a :b}

5

onsdag, 2010 november 03

Page 6: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

(println "Hello World")

function call

fn call argsemantics:

structure: symbol string

list

6

onsdag, 2010 november 03

Page 7: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

(defn greet "Returns a friendly greeting" [your-name] (str "Hello, " your-name))

function definition

define a fn fn namedocstring

arguments

fn body

7

onsdag, 2010 november 03

Page 8: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

(defn greet "Returns a friendly greeting" [your-name] (str "Hello, " your-name))

it's all data

symbol symbolstring

vector

list

8

onsdag, 2010 november 03

Page 9: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

(defn ^String greet "Returns a friendly greeting" [your-name] (str "Hello, " your-name))

metadata

prefix with ^ class name orarbitrary map

9

onsdag, 2010 november 03

Page 10: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

Clojure callingJava

10

onsdag, 2010 november 03

Page 11: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

java new

java new Widget("foo")

clojure sugar (Widget. "red")

11

onsdag, 2010 november 03

Page 12: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

access static members

java Math.PI

clojure sugar Math/PI

12

onsdag, 2010 november 03

Page 13: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

access instance members

java rnd.nextInt()

clojure sugar (.nextInt rnd)

13

onsdag, 2010 november 03

Page 14: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

chaining access

java person.getAddress().getZipCode()

clojure sugar (.. person getAddress getZipCode)

14

onsdag, 2010 november 03

Page 15: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

(doto (JFrame. "Foobar") (.add (proxy [JPanel] [])) (.setSize 640 400) (.setVisible true))

doto

frame is implicit arg for subsequent forms

15

onsdag, 2010 november 03

Page 16: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

parenthesis count

java ()()()()

clojure ()()()

16

onsdag, 2010 november 03

Page 17: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

example:refactor apache

commons isBlank

17

onsdag, 2010 november 03

Page 18: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

public class StringUtils { public static boolean isBlank(String str) { int strLen; if (str == null || (strLen = str.length()) == 0) { return true; } for (int i = 0; i < strLen; i++) { if ((Character.isWhitespace(str.charAt(i)) == false)) { return false; } } return true; }}

initial implementation

18

onsdag, 2010 november 03

Page 19: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

public class StringUtils { public isBlank(str) { if (str == null || (strLen = str.length()) == 0) { return true; } for (i = 0; i < strLen; i++) { if ((Character.isWhitespace(str.charAt(i)) == false)) { return false; } } return true; }}

- type decls

19

onsdag, 2010 november 03

Page 20: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

public isBlank(str) { if (str == null || (strLen = str.length()) == 0) { return true; } for (i = 0; i < strLen; i++) { if ((Character.isWhitespace(str.charAt(i)) == false)) { return false; } } return true;}

- class

20

onsdag, 2010 november 03

Page 21: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

public isBlank(str) { if (str == null || (strLen = str.length()) == 0) { return true; } every (ch in str) { Character.isWhitespace(ch); } return true;}

+ higher-order function

21

onsdag, 2010 november 03

Page 22: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

public isBlank(str) { every (ch in str) { Character.isWhitespace(ch); }}

- corner cases

22

onsdag, 2010 november 03

Page 23: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

(defn blank? [s] (every? #(Character/isWhitespace %) s))

Clojure!

23

onsdag, 2010 november 03

Page 24: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

objects,Clojure style

24

onsdag, 2010 november 03

Page 25: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

records

25

onsdag, 2010 november 03

Page 26: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

(defrecord Foo [a b c])-> user.Foo

defrecord

named typewith slots

(def f (Foo. 1 2 3))-> #'user/f positional

constructor(:b f)-> 2 keyword access

(class f)-> user.Foo

plain ol' class(supers (class f))-> #{clojure.lang.IObj clojure.lang.IKeywordLookup java.util.Map clojure.lang.IPersistentMap clojure.lang.IMeta java.lang.Object java.lang.Iterable clojure.lang.ILookup clojure.lang.Seqable clojure.lang.Counted clojure.lang.IPersistentCollection clojure.lang.Associative}

generic dataaccess

26

onsdag, 2010 november 03

Page 27: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

(def stu {:fname "Stu" :lname "Halloway" :address {:street "200 N Mangum" :city "Durham" :state "NC" :zip 27701}})

from maps...

27

(:lname stu)=> "Halloway"

keyword access

(-> stu :address :city)=> "Durham"

nested access

(assoc stu :fname "Stuart")=> {:fname "Stuart", :lname "Halloway", :address ...}

update

(update-in stu [:address :zip] inc)=> {:address {:street "200 N Mangum", :zip 27702 ...} ...}

nestedupdate

data-oriented

onsdag, 2010 november 03

Page 28: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

(defrecord Person [fname lname address])(defrecord Address [street city state zip])(def stu (Person. "Stu" "Halloway" (Address. "200 N Mangum" "Durham" "NC" 27701)))

...to records!

28

(:lname stu)=> "Halloway"

(-> stu :address :city)=> "Durham"

(assoc stu :fname "Stuart")=> :user.Person{:fname "Stuart", :lname"Halloway", :address ...}

(update-in stu [:address :zip] inc)=> :user.Person{:address {:street "200 N Mangum", :zip 27702 ...} ...}

still data-oriented:everything works

as before

object-oriented

type is therewhen you care

onsdag, 2010 november 03

Page 29: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

protocols

29

onsdag, 2010 november 03

Page 30: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

named set of generic functions

polymorphic on type of first argument

defines fns in same namespace as protocol

defprotocol

(defprotocol Coercions "Coerce between various 'resource-namish' things." (as-file [x] "Coerce argument to a file.") (as-url [x] "Coerce argument to a URL."))

30

onsdag, 2010 november 03

Page 31: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

(defrecord Name [n] Coercions (as-file [_] (File. n)))

(def n (Name. "johndoe"))

(as-file n)-> #<File johndoe>

extending inline

31

not a good design choice in this case, better approach

follows on next slide...

onsdag, 2010 november 03

Page 32: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

(as-file "data.txt")-> java.lang.IllegalArgumentException

extend protocol to types...

32

(extend-protocol Coercions nil (as-file [_] nil) (as-url [_] nil) String (as-file [s] (File. s)) (as-url [s] (URL. s))

(as-file "data.txt")-> #<File data.txt>

onsdag, 2010 november 03

Page 33: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

(extend-type String Coercions (as-file [s] (File. s)) (as-url [s] (URL. s)) EqualityPartition (equality-partition [x] :atom)

...or type to protocols

33

onsdag, 2010 november 03

Page 34: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

inline

extend protocol to multiple types

extend type to multiple protocols

build directly from fns and maps

extension happens in the protocol fns,not in the types

extending a protocol

34

onsdag, 2010 november 03

Page 35: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

(let [x 42 r (reify AProtocol (bar [this b] "reify bar") (baz [this ] (str "reify baz " x)))] (baz r))

=> "reify baz 42"

reify

instantiate an unnamed type

implement 0 or more protocols

or interfaces

closes overenvironment

like fn

35

onsdag, 2010 november 03

Page 36: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

Java callingClojure

36

onsdag, 2010 november 03

Page 37: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

(compile 'examples.clojure)

compiling

37

interactive

(defproject clojure.examples "0.0.1" :aot [examples.contacts] #_"...more maveny stuff”)

from a build tool/IDE(e.g. maven, leiningen, gradle, Eclipse, NetBeans,

IDEA, emacs, vim)

onsdag, 2010 november 03

Page 38: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

Address addr = new Address("200 N Mangum", "Durham", "NC", 27701);Person person = new Person("Stuart", "Halloway", addr);

System.out.println("As person " + person.fname);

System.out.println("As map");for (Iterator it = person.keySet().iterator(); it.hasNext();) { Object key = it.next(); System.out.println(key + ": " + person.get(key));}

Clojure data from Java

38

as objects

or asgeneric data

onsdag, 2010 november 03

Page 39: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

(ns examples.tasklist (:gen-class :extends org.xml.sax.helpers.DefaultHandler :init init :state state)

gen-class

39

class name

optional basesoptional

“constructor”optional state

onsdag, 2010 november 03

Page 40: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

(defn -init [] [[] (atom [])])

(defn -startElement [this uri local qname atts] (when (= qname "target") (swap! (.state this) conj (.getValue atts "name"))))

(defn -main [& args] (doseq [arg args] (println (task-list arg))))

mapping gen-class methods

40

constructor

inheritedmethod

static main

onsdag, 2010 november 03

Page 41: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

gen-class meets Java in ugly places

prefer defprotocol, defrecord, reify, deftype

previous slides were examples only

xml doesn’t have to be that tedious!

gen-class: for interop only

41

onsdag, 2010 november 03

Page 42: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

(defn tasklist [resource] (-> (read-html resource) (select [:target]) (attr :name)))

xml done better

42

clojure data

declarative, standards based query(courtesy cgrand’s enlive)

onsdag, 2010 november 03

Page 43: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

Clojure can call Java

Java can call Clojure

Clojure makes things better

so what?

where are we

43

onsdag, 2010 november 03

Page 44: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

simplicity

44

onsdag, 2010 november 03

Page 45: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

define simple

45

onsdag, 2010 november 03

Page 46: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

keepingcount?

46

onsdag, 2010 november 03

Page 47: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

“if I wanted to deploy a simple web app ... how many lines of text do I have to deal with?  Most importantly, how many of those are program text, and how many are framework boilerplate? Finally, how many tools do I have to use to get it deployed?”

simple things should be simple threadClojure google group

47

onsdag, 2010 november 03

Page 48: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

simple

48

onsdag, 2010 november 03

Page 49: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

still simple

49

onsdag, 2010 november 03

Page 50: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

complex

50

onsdag, 2010 november 03

Page 51: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

beginner-friendly?

51

onsdag, 2010 november 03

Page 52: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

“The most important gauge of any programming language is how easily a novice programmer can maintain a significant program in any problem domain.”

http://www.oreillynet.com/onlamp/blog/2006/03/the_worlds_most_maintainable_p.html

52

onsdag, 2010 november 03

Page 53: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

“Simplicity: Should be fairly simple to read, learn and understand. Python is a good example. PHP is a great example (at a simpler class of problems). C++ and Scala not good examples.”

http://blog.dhananjaynene.com/2010/08/my-ideal-programming-language/

53

onsdag, 2010 november 03

Page 54: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

54

http://www.aues21.dsl.pipex.com/orchestralinstruments.htm

onsdag, 2010 november 03

Page 55: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

familiarsyntax?

55

onsdag, 2010 november 03

Page 56: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

“Constructs that are natural to humans not mathematics : This is actually a sub point to Simplicity. The constructs should be consistent with the normal average non mathematically trained brains.”

http://blog.dhananjaynene.com/2010/08/my-ideal-programming-language/

56

onsdag, 2010 november 03

Page 57: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

minimal?

57

onsdag, 2010 november 03

Page 58: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

“If the semantic model of a language is clear - if its rules are simple and precise - the language will be more productive to use. Less is more.”

http://java.sun.com/developer/technicalArticles/JavaLP/jpl_proposals.html

58

onsdag, 2010 november 03

Page 59: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

uncomplicated?

59

onsdag, 2010 november 03

Page 60: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

http://twittch.com/26/

60

onsdag, 2010 november 03

Page 61: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

valuable, but not simpleconvenient

newb-friendly

easy

familiar syntax

minimal

uncomplicated

61

onsdag, 2010 november 03

Page 62: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

hopelesslysubjective?

62

onsdag, 2010 november 03

Page 63: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

“I’m coming to the conclusion that one man’s simple is another man’s complex.  Fowler evidently finds it easier to read many small methods than a few larger ones; I find the opposite.”

http://reprog.wordpress.com/2010/03/28/what-is-simplicity-in-programming/63

onsdag, 2010 november 03

Page 64: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

don’t give upsimple has an objective definition

simplicity informs design

simplicity is fundamental

64

onsdag, 2010 november 03

Page 65: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

simple: not compound

65

onsdag, 2010 november 03

Page 66: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

Java delivers compounds

66

onsdag, 2010 november 03

Page 67: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

objects provide...

Object

67

onsdag, 2010 november 03

Page 68: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

methods

Object

68

onsdag, 2010 november 03

Page 69: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

polymorphism

Object

onsdag, 2010 november 03

Page 70: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

types

Interface

Interface

Base Class

onsdag, 2010 november 03

Page 71: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

namespaces

Interface

Interface

Base Class

onsdag, 2010 november 03

Page 72: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

structure

Interface

Interface

Base Class

structxxxx yyyyzzzz

structxxxx yyyyzzzz

onsdag, 2010 november 03

Page 73: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

uncontrolled mutation

Interface

Interface

Base Class

structxxxx yyyyzzzz

Uncontrolled Mutation

onsdag, 2010 november 03

Page 74: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

pojo is an oxymoron

74

onsdag, 2010 november 03

Page 75: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

features are delivered as compounds

compounds contain more than you need

snowballs from language into libs

Java* style:compound, complex, complicated

75

onsdag, 2010 november 03

Page 76: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

Clojure deliverssimples &

composites

76

onsdag, 2010 november 03

Page 77: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

foundationidentity

generic dataaccessvalues

perception

functions

Vars

structxxxx yyyyzzzz

namespaces

typespolymorphism

structure

77

onsdag, 2010 november 03

Page 78: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

superstructure

identity

generic dataaccessvalues

perception

functions

Vars

structxxxx yyyyzzzz

namespaces

typespolymorphism

structure

78

onsdag, 2010 november 03

Page 79: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

examples

79

onsdag, 2010 november 03

Page 80: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

polymorphisma la carte

identity

generic dataaccessvalues

perception

functions

Vars

structxxxx yyyyzzzz

namespaces

typespolymorphism

structure

80

onsdag, 2010 november 03

Page 81: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

(extend-protocol Coercions nil (as-file [_] nil) (as-url [_] nil) String (as-file [s] (File. s)) (as-url [s] (URL. s))

Coercions

extend to existing types

implementation contract!= caller API

81

(defprotocol Coercions "Coerce between various 'resource-namish' things." (as-file [x] "Coerce argument to a file.") (as-url [x] "Coerce argument to a URL."))

onsdag, 2010 november 03

Page 82: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

extension options revisited

82

inline

extend types to protocol

extend protocol to types

build directly from fns and maps

onsdag, 2010 november 03

Page 83: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

implementationreuse

83

onsdag, 2010 november 03

Page 84: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

(extend BufferedInputStream IOFactory (assoc default-streams-impl :make-input-stream (fn [x opts] x) :make-reader inputstream->reader))

extend

plain ol’ keywords and fnsno special mixin

API: use generic collection fns

84

onsdag, 2010 november 03

Page 85: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

;; elided from clojure.java.io(def default-streams-impl {:make-reader (fn [x opts] ...) :make-writer (fn [x opts] ...) :make-input-stream (fn [x opts] ...) :make-output-stream (fn [x opts] ...)})

mere maps

make a mapof names -> fns...

85

onsdag, 2010 november 03

Page 86: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

simple syntax:singular

interpretation

86

onsdag, 2010 november 03

Page 87: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

(verb & args)

form example

function (println "hello")

operator (+ 1 2)

method call (.trim " hello ")

import (require 'mylib)

metadata (with-meta obj m)

control flow (when valid? (proceed))

scope (dosync (alter ...))

87

onsdag, 2010 november 03

Page 88: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

[bindings]

form example

fn (fn [x] (* x 2))

named fn (defn hi [s] (str "hi, " s)

lexical bind (let [[x y] (range) ...)

dynamic bind (binding [answer 42] ...)

comprehension (for [x (range) ...] ...)

side effects (doseq [{m :msg} warnings]...)

88

onsdag, 2010 november 03

Page 89: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

genericdata access

identity

generic dataaccessvalues

perception

functions

Vars

structxxxx yyyyzzzz

namespaces

typespolymorphism

structure

89

onsdag, 2010 november 03

Page 90: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

lunch-companions-> ({:fname "Neal", :lname "Ford"} {:fname "Stu", :lname "Halloway"} {:fname "Dan", :lname "North"})

some data

90

onsdag, 2010 november 03

Page 91: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

(defn last-name [x] (get x :last-name)

“getter” function

fn name arg list (vector)

body

91

onsdag, 2010 november 03

Page 92: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

(sort-by first-name lunch-companions)-> ({:fname "Dan", :lname "North"} {:fname "Neal", :lname "Ford"} {:fname "Stu", :lname "Halloway"})

pass fn to fn

invoke this fnfn arg

data arg

92

onsdag, 2010 november 03

Page 93: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

(sort-by (fn [n] (get n :fname)) lunch-companions)

anonymous fn

anonymous fn

fn arg

body

93

onsdag, 2010 november 03

Page 94: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

(sort-by #(get % :fname) lunch-companions)

anonymous #()

anonymous fn

fn arg

94

onsdag, 2010 november 03

Page 95: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

(sort-by #(% :fname) lunch-companions)

maps are functions

map is fn!

95

onsdag, 2010 november 03

Page 96: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

(sort-by #(:fname %) lunch-companions)

keywords are functions

keyword is fn!

96

onsdag, 2010 november 03

Page 97: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

(sort-by :fname lunch-companions)

beautiful

97

onsdag, 2010 november 03

Page 98: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

direct accessto the jvm

98

onsdag, 2010 november 03

Page 99: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

performance

power

reach

living on the jvm

99

onsdag, 2010 november 03

Page 100: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

primitive operations

collection conformance

absence of tco

oo interop (genclass, proxy)

alternate numeric ops

jvm tradeoffs

100

onsdag, 2010 november 03

Page 101: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

(def nums (make-array Integer/TYPE 10))-> #'user/nums

(aset nums 4 1000)-> 1000

(aget nums 4)-> 1000

(seq nums)-> (0 0 0 0 1000 0 0 0 0 0)

arrays

101

onsdag, 2010 november 03

Page 102: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

(def nums (range 3))(defn member-type [arr] (-> arr class (.getComponentType)))

(-> (to-array nums) member-type)-> java.lang.Object

(-> (into-array nums) member-type)-> java.lang.Integer

(-> (into-array Comparable nums) member-type)-> java.lang.Comparable

converting to arrays

always Object

inferred from first member

explicit

102

onsdag, 2010 november 03

Page 103: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

(defn fib [n] (if (<= n 1) 1 (+ (fib (dec n)) (fib (- n 2)))))

(time (fib 38))"Elapsed time: 3565.579 msecs"

;; hint arg and return(defn fib ^long [^long n] (if (<= n 1) 1 (+ (fib (dec n)) (fib (- n 2)))))

(time (fib 38))"Elapsed time: 395.365 msecs"

unboxed math (1.3+)

hint only whereneeded, inferencehandles the rest

103

onsdag, 2010 november 03

Page 104: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

(defn zipm [keys vals] (loop [m {} ks (seq keys) vs (seq vals)] (if (and ks vs) (recur (assoc m (first ks) (first vs)) (next ks) (next vs)) m)))

(zipm [:a :b :c] [1 2 3]) => {:a 1, :b 2, :c 3}

explicit tco

104

onsdag, 2010 november 03

Page 105: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

(loop [m {} [k & ks :as keys] (seq keys) [v & vs :as vals] (seq vals)] (if (and keys vals) (recur (assoc m k v) ks vs) m))

;reduce with adder fn(reduce (fn [m [k v]] (assoc m k v)) {} (map vector keys vals))

;apply data constructor fn(apply hash-map (interleave keys vals))

;map into empty (or not!) structure(into {} (map vector keys vals))

;get lucky(zipmap keys vals)

loops are rare

105

onsdag, 2010 november 03

Page 106: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

(deftype ^{Deprecated true} Foo [^{Retention RetentionPolicy/RUNTIME} a b])

annotations

106

plain ol’ Clojure metadata

with keys and valuesas required by annotation

onsdag, 2010 november 03

Page 107: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

numeric options

107

java default N VF N L N

java big Y S N/A A N/A

clojure default Y F* Y L Y*

clojure big Y S N/A A N/A

clojure unchecked N VF Y L N

safety

?

spee

dca

nonic

al?

prec

ision

cont

agion

?

ArbitraryFastLimitedNoNot ApplicableBlowVery FastYes* (caller choose one)

onsdag, 2010 november 03

Page 108: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

example:reflection

108

onsdag, 2010 november 03

Page 109: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

(reflect "Foo")(reflect [1 2 3])

(reflect FileInputStream)

sure wish we could...

109

onsdag, 2010 november 03

Page 110: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

(show "foo" #"last")=== public final java.lang.String ===[56] lastIndexOf : int (String)[57] lastIndexOf : int (String,int)[58] lastIndexOf : int (int)[59] lastIndexOf : int (int,int)

history: repl-utils/show

110

onsdag, 2010 november 03

Page 111: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

query

describe

invoke

class in hand

class in context

java reflection is compound

111

onsdag, 2010 november 03

Page 112: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

approach

Reflectorreflect

1. single api

->>2. generic

wiring

predicates(clojure.data.match TBD)

3. genericpredicates

print-table4. genericprinting

112

onsdag, 2010 november 03

Page 113: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

(->> (reflect java.lang.String) :members (filter #(.startsWith (str (:name %)) "last")) (print-table))

===================================================================================================================:name | :return-type | :declaring-class | :parameter-types | :exception-types | :flags ===================================================================================================================lastIndexOf | int | java.lang.String | [java.lang.String] | [] | #{:public}lastIndexOf | int | java.lang.String | [char<> int int char<> int int int] | [] | #{:static}lastIndexOf | int | java.lang.String | [int] | [] | #{:public}lastIndexOf | int | java.lang.String | [java.lang.String int] | [] | #{:public}lastIndexOf | int | java.lang.String | [int int] | [] | #{:public}===================================================================================================================

usage

113

onsdag, 2010 november 03

Page 114: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

// from java.lang.reflect.Modifierpublic static final int PUBLIC = 0x00000001;public static final int PRIVATE = 0x00000002;public static final int PROTECTED = 0x00000004;public static final int STATIC = 0x00000008;public static final int FINAL = 0x00000010;public static final int SYNCHRONIZED = 0x00000020;public static final int VOLATILE = 0x00000040;public static final int TRANSIENT = 0x00000080;

modeling classfiles, poorly

114

onsdag, 2010 november 03

Page 115: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

classes are poor containers

no data literals to use instead

modifiers, types add no value

data doesn’t capture the model

problems

115

onsdag, 2010 november 03

Page 116: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

(defn- access-flag [[name flag & contexts]] {:name name :flag flag :contexts (set (map keyword contexts))})

(def flag-descriptors (vec (map access-flag [[:public 0x0001 :class :field :method] [:private 0x002 :class :field :method] [:protected 0x0004 :class :field :method] [:static 0x0008 :field :method] [:final 0x0010 :class :field :method] [:synchronized 0x0020 :method] [:volatile 0x0040 :field] [:bridge 0x0040 :method]])))

knowledge is data

116

onsdag, 2010 november 03

Page 117: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

irrelevant destractions

117

field

method

constructor

member

modifier

onsdag, 2010 november 03

Page 118: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

(defprotocol Reflector "Protocol for reflection implementers." (do-reflect [reflector typeref]))

(defprotocol TypeReference "A TypeReference can be unambiguously converted to a type name on the host platform." (typename [o]))

relevant abstractions

118

onsdag, 2010 november 03

Page 119: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

(defn reflect [obj & options] (apply type-reflect (if (class? obj) obj (class obj)) options))

abstractions != api

119

onsdag, 2010 november 03

Page 120: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

(->> (reflect java.lang.String) :members (filter #(.startsWith (str (:name %)) "last")) pprint)

({:name lastIndexOf, :return-type int, :declaring-class java.lang.String, :parameter-types [java.lang.String], :exception-types [], :flags #{:public}} {:name lastIndexOf, :return-type int, :declaring-class java.lang.String, :parameter-types [char<> int int char<> int int int], :exception-types [], :flags #{:static}} ...)

information ~ maps

120

onsdag, 2010 november 03

Page 121: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

Clojure fits if you value

simplicity and directness

over

convenience and familiarity121

onsdag, 2010 november 03

Page 122: Clojure-Java Interop - QCon San Francisco 2018 | … · the plan 2 syntax plumbing Clojure calling Java objects, Clojure style Java calling Clojure design principles simplicity direct

thanks!

http://clojure.org

122

onsdag, 2010 november 03