83462

How do I implement this generic Java interface with a Clojure record?

Question:

I'm trying to implement <a href="http://joda-time.sourceforge.net/apidocs/org/joda/time/ReadableInstant.html" rel="nofollow">org.joda.time.ReadableInstant</a>. It inherits from a generic interface, but apparently that shouldn't matter. <a href="https://github.com/JodaOrg/joda-time/blob/1379098f681f0d4d6f0a3403ab6727dc3437b6df/src/main/java/org/joda/time/ReadableInstant.java" rel="nofollow">The interface</a> is:

public interface ReadableInstant extends Comparable<ReadableInstant> { long getMillis(); Chronology getChronology(); DateTimeZone getZone(); int get(DateTimeFieldType type); boolean isSupported(DateTimeFieldType field); Instant toInstant(); boolean isEqual(ReadableInstant instant); boolean isAfter(ReadableInstant instant); boolean isBefore(ReadableInstant instant); boolean equals(Object readableInstant); int hashCode(); String toString(); }

My record:

(defrecord WeirdDate [year month day] ReadableInstant (^boolean equals [this ^Object readableInstant] (.equals (as-date this) readableInstant)) (^int get [this ^DateTimeFieldType type] (get (as-date this) type)) (^Chronology getChronology [this] (.getChronology (as-date this))) (^long getMillis [this] (.getMillis (as-date this))) (^DateTimeZone getZone [this] (.getZone (as-date this))) (^int hashCode [this] (.hashCode (as-date this))) (^boolean isAfter [this ^ReadableInstant instant] (.isAfter (as-date this) instant)) (^boolean isBefore [this ^ReadableInstant instant] (.isBefore (as-date this) instant)) (^boolean isEqual [this ^ReadableInstant instant] (.isEqual (as-date this) instant)) (^boolean isSupported [this ^DateTimeFieldType field] (.isSupported (as-date this) field)) (^Instant.toInstant [this] (.toInstant (as-date this))) (^String toString [this] (.toString (as-date this))))

But I get the error:

java.lang.IllegalArgumentException: Must hint overloaded method: get

Are my type hints wrong? Is there something else wrong?

(Apologies for those of you on the <a href="https://groups.google.com/d/msg/clojure/4v9VGcFC5GM/JXHBonWwPXEJ" rel="nofollow">Clojure mailing list where I've already asked a longer version of this question</a>, I thought that a shorter question here might be easier to answer)

Answer1:

You can't use a defrecord to implement a type with a get method, because get is already defined on java.util.Map, which defrecord automatically implements for you. If you want to implement this interface, you will have to forego the niceties of mappiness and just use a plain deftype. Also, every type hint in your code is completely unnecessary: the compiler knows the types of the interface you're implementing, and doesn't need your help to figure them out.

Recommend