You can hint a return type in a protocol
(defprotocol Individual
(^Integer age [this]))
and the compiler will make your methods comply:
(defrecord person []
Individual
(^String age [this] "one"))
; CompilerException java.lang.IllegalArgumentException: Mismatched return type: age, expected: java.lang.Object, had: java.lang.String, ...
But you don't have to honour the type-hint:
(defrecord person []
Individual
(age [this] "one"))
(age (new person))
; "one"
Does the type-hint have any effect?
This is a follow up to Can you specify the return type of a method in a clojure defrecord?
The return type hint goes to the protocol function age
as tag. From there, the tag is used in local type inference. To observe this in action:
- (.longValue (age (new person)))
ClassCastException java.lang.String cannot be cast to java.lang.Integer
net.bendlas.lintox/eval18038 (form-init4752901931682060526.clj:1)
;; longValue is a method of Integer, so a direct cast has been inserted
If the type hint had been left off, or if you call a method not on the hinted type, the compiler inserts a (slow) call into the reflector, instead of the plain cast:
- (.otherMethod (age (new person)))
IllegalArgumentException No matching field found: otherMethod for class java.lang.String clojure.lang.Reflector.getInstanceField (Reflector.java:271)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With