Skip to content

Instantly share code, notes, and snippets.

@pjstadig
Created March 20, 2017 13:06
Show Gist options
  • Save pjstadig/6fa4ebf465f6d438b4dcc2a5bfbb3db6 to your computer and use it in GitHub Desktop.
Save pjstadig/6fa4ebf465f6d438b4dcc2a5bfbb3db6 to your computer and use it in GitHub Desktop.
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.
@borkdude
Copy link

borkdude commented Apr 1, 2022

@cursive-ide Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment