Search code examples
clojureclojure-java-interop

Scope of type hints in Clojure?


I am seeking information on the scope of type hints in Clojure, for instance, if I write

(defn big-add [^BigInteger x y] (.add x y))

is that the same as

(defn big-add [^BigInteger x ^BigInteger y] (.add x y))

? Suppose I write

(defn big-sum 
  ([] BigInteger/ZERO)
  ([^BigInteger x] x)
  ([^BigInteger x & more] (.add x (apply big-sum more) )))

Does Clojure assume that more is full of BigInteger? Suppose I want to tell it not? Would I do something like

(defn foo [^BigInteger x & ^Long more] ...)

?


Solution

  • Simply set warn-on-reflection true and test your expressions with a function where the type can't be resolved.

    REPL:

    (set! *warn-on-reflection* true)
    (defn testo [s]
          (str s))
    => #'user/testo
    
    (defn testo [s]
          (.charAt s 1))
    => Reflection warning, NO_SOURCE_PATH:2:8 - call to charAt can't be resolved.
    
    (defn testo [^java.lang.String s]
          (.charAt s 1))
    => #'user/testo
    
    (defn testo [^java.lang.String s s2]
          (.charAt s2 1))
    => Reflection warning, NO_SOURCE_PATH:2:8 - call to charAt can't be resolved.
    
    (defn testo [^java.lang.String s & more]
          (.charAt (first more) 1))
    => Reflection warning, NO_SOURCE_PATH:2:8 - call to charAt can't be resolved.
    

    And finally

    (defn testo [s & ^java.lang.String more]
          (.charAt (first more) 1))
    => CompilerException java.lang.RuntimeException: & arg cannot have type hint, compiling:(NO_SOURCE_PATH:1:1) 
    

    The short answer to each of your questions is no :(