Hi,

I'm porting some JDK 8 code to JDK 9 and hit a snag that boils down to "an
interface, of which I tried to implement all the methods, suddenly grew a
few static methods and deftype doesn't know how to do that". I tried
^:static and ^{:static true}.

You can try this as follows: java.util.Map grew a handful of static methods
in JDK9 where previously it had none. Try:

(deftype MyMap [obj]
  java.util.Map
  ^{:static true} (entry [k v] nil))

This fails, saying there's no `entry` method in java.util.Map. (There is,
at least on JDK9! But it's static.) I have also tried putting the metadata
on the method name symbol and the params, but no dice.

Underlying context need: Clojure's maps are both iterable and associative,
implementing both Java interfaces. The GCP StackDriver code that tries to
serialize values typechecks to figure out what to do with  a type, but it
typechecks in the wrong order: it checks for iterability before
associativity. So it treats {} as a seq and that works but it looks
terrible in the logs. Hence, I have a silly macro that generates a silly
stub class that only implements the 1 right interface and proxies all
method calls to the Clojure datatype. Here's the implementation of that
macro and a sample use case:



(defmacro defproxytype
  [type-name iface-sym]
  (let [iface (Class/forName (str iface-sym))
        {:keys [members]} (refl/reflect iface)
        wrapped-obj '(.-obj this)]
    `(deftype ~type-name [~(with-meta 'obj {:tag iface})]
       ~iface-sym
       ~@(for [{:keys [name parameter-types return-type]} members
               :let [m (with-meta (symbol name) {:tag return-type})
                     args (map (fn [arg-idx arg-type]
                                 (with-meta
                                   (symbol (str "arg" arg-idx))
                                   {:tag arg-type}))
                               (range) parameter-types)]]
           `(~m [~'this ~@args] (. ~wrapped-obj ~m ~@args))))))

(defproxytype JustAMap java.util.Map)


Then, I walk the tree and wrap all maps with ->JustAMap. As you can see,
while technically I might be able to use gen-class somehow, this is
something where deftype shines :-) Fortunately right now the caller doesn't
use any of the static methods and generally speaking I'd expect them not to
(kind of by definition) -- so my workaround is just to not implement any of
the static methods and hope for the best. Still, if there's a way, I'd love
to know :)


lvh

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to