4 ms·
There's no good way to extend abstract classes. If you're using proxy, you pay a large performance penalty, and you can't call protected superclass methods or
by Scarbutt 6y ago
There's no good way to extend abstract classes.
If you're using proxy, you pay a large performance penalty, and you can't call protected superclass methods or access protected superclass fields without using reflection.
gen-class is a truly awful thing to use.
Even when type hinted, defrecord fields all have type Object.
primitive type hinting, and corners like the type hinting in deftype/reify (where you have to either type hint everything or nothing)
Having to type hint with ^"[Lcom.example.project.package.Class;" is foul.
No niceties like SAM conversion, No integration with java.util.function interfaces.
- grzm 6y agoThanks for the examples! There are some things that aren't as easy. And sometimes it's a better choice to drop into Java to provide a shim between the package you're interacting with and Clojure to make the interop easier, or when performance matters. Regarding hinting for defrecord fields and deftype/reify, do you have references where this has been a problem for you? It's not something I've run into, but that's just my experience. As for java.util.function interfaces, I just did this within the past couple of weeks, which worked for my use case: defn ^java.util.function.Function as-function [f] (reify java.util.function.Function (apply [this arg] (f arg)))) For SAM conversions in general, there's https://github.com/ajoberstar/ike.cljj https://github.com/ajoberstar/ike.cljj . I haven't used it myself, but perhaps the pattern used there would work in you. It sounds like what you've worked on has been relatively performance sensitive, which can definitely a thing. So perhaps some of these interop suggestions won't work for you. Again, thanks for taking the time to be more explicit about what you've found frustrating.
- skissane 6y agoI wonder, are the Clojure developers planning to fix these deficiencies? Most or all of them are things which could be fixed with some work.
- grzm 6y agoI'm not sure where these items fall in their priorities. You can explore issues that are tracked on the JIRA instance here: https://clojure.atlassian.net/jira/software/c/projects/CLJ/issues/?filter=allissues https://clojure.atlassian.net/jira/software/c/projects/CLJ/i... A couple that are related to the items 'Scarbutt mentioned: - https://clojure.atlassian.net/browse/CLJ-2365 https://clojure.atlassian.net/browse/CLJ-2365 Integration with java.util.function interfaces - https://clojure.atlassian.net/browse/CLJ-1255 https://clojure.atlassian.net/browse/CLJ-1255 Support Abstract Base Classes with Java-only variant of "reify" - https://clojure.atlassian.net/browse/CLJ-1001 https://clojure.atlassian.net/browse/CLJ-1001 Proxy cannot call proper super-class method My take on this is that Clojure provides host (Java) interop, not replacement. Part of that is if you're doing really Java-y things, such as extending abstract classes, that's probably better done in Java. These class-based inheritance/extension concepts aren't core to what Clojure is about. Polymorphism and extension is addressed by other means in Clojure. A comparison: I know little about Kotlin, but I wouldn't be surprised if it has a better story about Java class extension and interface implementation as I think one of its goals is to be in some ways a better Java. I don't think that's a goal that Clojure shares. If those are features you are looking for, Clojure may not be a good fit.