When I was working on cats.typed I quite often was wondering if there is something like Rosetta Stone for TypedClojure. A place where I could find type declarations in Scala or Java, and corresponding declarations for Clojure. As I have not found such place, so I was inspired to write this post. It contains only few basic cases, yet, it still could be useful to make the first steps.

Function with no arguments and no return value

Java

public void printlnString() {
  System.out.println("void");
}

Scala

def printlnString(): Unit = {
  println("void")
}

Clojure

(t/ann println-string [-> (t/Value nil)])
(defn println-string
  []
  (println "void"))

Function with a single argument and return value

Java

public Integer stringToInt(String a) {
  return Integer.parse(a);
}

Scala

def stringToInt(a: String): Int = {
  a.toInt
}

Clojure

(t/ann string-to-int [String -> Integer])
(defn string-to-int
  [a]
  (Integer/parseInt a))

Function with two arguments and return value

Java

public Long sumArgsLength(String a, String b) {
  return Long.valueOf(a.length() + b.length());
}

Scala

def sumArgsLength(a: String, b: String): Long = {
  (a.length + b.length).toLong
}

Clojure

(t/ann sum-args-length [String String -> Long])
(defn sum-args-length
  [^String a ^String b]
  (long
   (+ (.length a) (.length b))))

Function with typed argument and return value

Java

class Custom<T> {
  T name;
}

public String getCustomName(Custom<String> custom) {
  return custom.name;
}

Scala

case class Custom[T](name: T)

def getCustomName(custom: Custom[String]): String = {
  custom.name
}

Clojure

(t/ann-record [[type :variance :invariant]]
              Custom
              [name :- type])
(defrecord Custom [name])

(t/ann get-custom-name [(Custom String) -> String])
(defn get-custom-name [custom] (:name custom))

Errata:

  • (2016-01-31) changed :covariant to :invariant in last example