JVM Interop

Principles & Practice

Marshall Bockrath-Vandegrift
atl-clj / 2013-08-13

Clojure ⬌ Java

Methods vs Types

  • Verbs vs Nouns

  • Functions vs Objects

  • Clojure → vs ← Java

Clojure ➡ Java

Seeing through Java’s lies

Methods

Instance methods

(.methodName object arg0 arg1)
(. object methodName arg0 arg1)

Static methods

(Type/methodName arg0 arg1)
(. Type methodName arg0 arg1)

Hinting overloads

(.methodName object ^Type arg0)

Varargs

Type methodName(Type args...)
(.methodName object (into-array Type args))

Types

Construction

(Type. arg0 arg1)
(new Type arg0 arg1)

Inner classes

import package.Outer.Inner;
(import '[package Outer$Inner])

“Hostedness”

(instance? java.lang.String "foo")
(instance? java.util.List [])
(instance? java.util.Map {})
(instance? java.util.Set #{})

Clojure ⬅ Java

“Java happens”

Methods

Ha ha! Just kidding.

Functions qua functions

(instance? java.lang.Runnable (fn []))
(instance? java.util.Comparator (fn []))
(instance? java.util.concurrent.Callable (fn []))

Functions in object clothing

(reify Interface
  (someMethod [this arg0 arg1] result))

Objects in object clothing

reify vs gen-class – when to use?

  • reify – anonymous, interfaces

  • gen-classnever

contra gen-class

  • Forced AOT compliation

  • Semi-abandoned

  • Complex & awkward interface

Java

Up from Java

class ActualClass extends AbstractBaseClass {
  private static class Vars {
    private static final String NS = "some.namespace";
    private static final Var someFunction =
       RT.var(NS, "some-function");
    static {
      RT.var("clojure.core", "require").invoke(Symbol.intern(NS));
    }
  }

  @SomeAnnotation("arg")
  public Object someMethod(Object arg) {
    return Vars.someFunction.invoke(arg);
  }
}

Edge cases

  • proxy

Not edge cases

  • deftype

Finis