Share your thoughts in the 2024 State of Clojure Survey!

Welcome! Please see the About page for a little more info on how this works.

+1 vote
in Protocols by

The following example will cause a runtime class cast exception. There appears to be no way to add a type annotation of ^long to a protocol as it will either get a compile time error or a runtime error.

(defprotocol my-protocol-1
    (my-func-1 [this value]))

(deftype my-type-1 [x]
    my-protocol-1
    (my-func-1 [this value]
        (* value 2)))

(def z1 (my-type-1. 123))

(println (my-func-1 z1 99)) ;; this works

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


(defprotocol my-protocol-2
    (my-func-2 [this ^long value]))  ;; only a type hit has been added

(deftype my-type-2 [x]
    my-protocol-2
    (my-func-2 [this value]
        (* value 2)))

(def z2 (my-type-2. 123))

(println (my-func-2 z2 456)) ;; will cause exception
                             ;; class user$eval180$fn__181$G__171__188 cannot be cast to class clojure.lang.IFn$OLO

2 Answers

+1 vote
by

If you want primitive types, use definterface.

0 votes
by

You can not use long in clj
This is a cljs thing. In clj you should use Long

When you use long in clj, it resolves to clojure.core/long, that is a function. Then it fail to match the type

by
`^Long` is the `java.lang.Long` type which is boxed.  Using `^long` it will annotate the interface with the unboxed long type
...