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

0 votes
in Java Interop by

Currently implementing a custom java.util.Iterator with the usual deftype form like

(deftype MyIterator []
  Iterator
  (hasNext [this]
    (my-custom-code))
  (next [this]
    (my-custom-code))
)

But I'd like to override the forEachRemaining default method on Iterator:

default void forEachRemaining(Consumer<? super E> action) {
    Objects.requireNonNull(action);
    while (hasNext())
        action.accept(next());
}

... with a more performant/specialized implementation. Perhaps I would even want to implement the by-default unimplemented remove:

default void remove() {
    throw new UnsupportedOperationException("remove");
}

But deftype does not allow for overriding methods. Is this a fundamental limitation or just something that hasn't been done (probably because Clojure predates default methods in java 8)? Anyways as a language whose philosophy is to embrace the the host, this would come in highly useful for using/integrating with java interfaces.

2 Answers

+1 vote
by
selected by
 
Best answer

Did you actually try this? Because it seems to work for me now.

(deftype MyIterator []
  java.util.Iterator
  (hasNext [this] false)
  (next [this] 0)
  ;; try to override default method
  (remove [this] (println "boo")))

(.remove (MyIterator.))
;; boo
by
Sorry I think I must have been doing something wrong when I was trying this, and might have misunderstood the error I got. Thanks!
+1 vote
by

It is intentional that deftype only allows implementing interfaces and not extending concrete types, but that work predated the existence of default methods on interfaces, which does seem like something that should be supported. Will file a jira for a request tomorrow...

...