A little type hint hint
| (ns typehint.core) | |
| ;; A little type hint hint... | |
| (set! *warn-on-reflection* true) | |
| ;; There are two ways to type hint the return value of a function, but one is | |
| ;; (technically) wrong: | |
| (defn ^String as-string0 | |
| [obj] | |
| (str obj)) | |
| (defn as-string1 | |
| ^String [obj] | |
| (str obj)) | |
| (.length (as-string0 '(:a :b))) ; <- no reflection warning | |
| (.length (as-string1 '(:a :b))) ; <- no reflection warning | |
| ;; But the first actually means something more than just the return value of the | |
| ;; function, it means the value of the var is a String. | |
| (def ^String a-string | |
| "Hello, World!") | |
| (defn to-string0 | |
| [] | |
| (.length a-string) ; <- no reflection warning | |
| (.length as-string0) ; <- weird, but no reflection warning | |
| ) | |
| (defn to-string1 | |
| [] | |
| (.length as-string1) ; <- weird, and reflection warning | |
| ) | |
| ;; Why is this? Originally, Clojure did not use type hints on the argument | |
| ;; vector. To type hint the return value of a function you would put a type | |
| ;; hint on the var (the first method). In version 1.3 Clojure got primitive | |
| ;; arguments and return values for functions, and those are indicated by putting | |
| ;; the type hint on the args and on the arg vector (the second method). | |
| ;; | |
| ;; AFAIK, the only reason the first method even works for return values is for | |
| ;; backwards compatibility. If you put a type hint on the var you are saying | |
| ;; the value of that var will be that type. The correct way to type hint a | |
| ;; return value is to put the hint on the arg vector. | |
| ;; | |
| ;; This also means you can have different return hints for different arities | |
| ;; (though I would question why you'd want that!). | |
| (defn ambiguous | |
| (^String [] | |
| "foo") | |
| (^Integer [_] | |
| (int 5))) | |
| (defn confusing | |
| [] | |
| (.length (ambiguous)) ; <- no reflection warning | |
| (.longValue (ambiguous nil)) ; <- also no reflection warning | |
| ) | |
| ;; == SUMMARY | |
| ;; If you want to type hint the *content* of a var, put the type hint on the | |
| ;; var. | |
| ;; If you want to type hint the return value of a function, put the type hint on | |
| ;; the argument vector. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This comment has been minimized.
cursive-ide commentedDec 15, 2017
I think @Bronsa pointed this out on Twitter, but in Clojure <= 1.7, when you type hint the arg vector the symbol is not evaluated. This means that if you type hint with the short name of a class you have imported where the function is defined, if that same class is not imported in the namespace where the function is invoked, things will break: