Mikera, I think you're addressing a different interop concern. I'm particularly interested in something like this:
(-> (IntStream/range 0 100) (.filter odd?) (.limit 5) (.collect Collectors/toList)) Where "odd?" is a normal Clojure IFn that I want to use when calling a Java API that expects something implementing a single-method-interface (Predicate in this case). Right now I need to do something like this: (defn lambda [f] (reify Predicate (test [x] (f x)))) (-> (IntStream/range 0 100) (.filter (lambda odd?)) (.limit 5) (.collect Collectors/toList)) Andrew Oberstar On Mon, Jul 27, 2015 at 8:16 PM Mikera <mike.r.anderson...@gmail.com> wrote: > It could certainly be achieved in the Clojure compiler, by allowing > (some-functional-interface .....) to compile to the appropriate function > call even if it doesn't implement IFn > > It would be quite a big change though and would probably have some > limitations, e.g.: > a) It probably wouldn't work with regular vars since it wouldn't be able > to handle re-binding > b) You would probably have to type hint the "some-functional-interface" > object in some way so that the compiler knows to do this at compile time > > A less invasive option would be to just have some code to wrap functional > interfaces in an appropriate IFn. > > Worth a JIRA ticket for consideration at least? > > > > On Tuesday, 28 July 2015 08:52:47 UTC+8, Andrew Oberstar wrote: > >> Thanks for the reply Gary. Sounds like I'm on as good a track as I can >> be with current Clojure. >> >> I am curious though why you say that it is unrealistic for IFn to support >> arbitrary @FunctionalInterface. It certainly seems like it would require >> compiler changes, but I would think that either through emitting bytecode >> closer to Java 8 lambdas or through some form of type coercion it would >> possible. For example, Groovy just coerces their Closures to any Single >> Abstract Method type. >> >> I'm not sure how java.util.function.* as protocols would work, but still >> would require implementing for each SAM you come across. IFn as a protocol >> seems to address a different interop use case. Maybe for receiving a Java >> lambda you want to use as if it's a Clojure function. >> >> Most of the Java interop from Clojure is slick (sometimes more clear than >> in Java itself), it would be unfortunate to leave functions as second-class >> citizens for interop. Granted, there may be a simplicity argument against >> this (maybe that's why Java varargs require an explicit array?). >> >> Andrew Oberstar >> >> On Mon, Jul 27, 2015 at 4:16 AM Gary Verhaegen <gary.ve...@gmail.com> >> wrote: >> >>> On Sunday, 26 July 2015, Andrew Oberstar <ajobe...@gmail.com> wrote: >>> >>>> Hi, >>>> >>>> I'm wondering if anyone has a good approach for making calls from >>>> Clojure to Java APIs (e.g. Stream API) that expect a @FunctionalInterface >>>> type. >>>> >>>> Ideally, IFn would transparently work, but I'm guessing that requires >>>> some compiler changes. >>>> >>>> Right now, the best I can think of is a function or macro to reify a >>>> wrapper around a Clojure function to implement all of the usual interfaces >>>> from java.util.function. >>>> >>>> Anyone have any better ideas? >>>> >>>> Andrew Oberstar >>>> >>> >>> You're probably aware of this, but @FunctionalInterface is not a type, >>> it's an annotation. All it does is ensure, at compile time, that the >>> annotated element is an interface with a single non-default and non-static >>> method. At the type-system level, it's just an interface like any other, >>> and the lambda syntax is just a shorthand for an anonymous instance of a >>> well-defined type. >>> >>> Since the lambda syntax is java-compiler magic, you can't access it from >>> Clojure, and the most straightforward option right now is to actually know >>> which type is expected, e.g.: >>> >>> user=> (-> (doto (java.util.ArrayList.) (.add 1) (.add 2)) (.stream) >>> (.map (reify java.util.function.Function (apply [_ arg] (inc arg)))) >>> (.collect (java.util.stream.Collectors/toList))) >>> [2 3] >>> user=> >>> >>> As neither IFn nor Function are Clojure protocols, I do indeed think >>> you're best bet is a macro to essentially generate the above reify. You can >>> of course do a single macro that reifies to all of the protocols that you >>> need. >>> >>> I don't think it's realistic to hope that IFn will cover any arbitrary >>> @FunctionalInterface, as that is Java compiler magic. It may, in the >>> future, be extended to cover all of the standard ones in >>> java.util.function, or even all the ones in the standard library, but it's >>> not going to happen until Java 7 support is dropped. I guess the best you >>> could hope for in the short term would be to have IFn changed to a protocol. >>> >>> -- >>> You received this message because you are subscribed to the Google >>> Groups "Clojure" group. >>> >> To post to this group, send email to clo...@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+u...@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+u...@googlegroups.com. >> >> >>> For more options, visit https://groups.google.com/d/optout. >>> >> -- 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.