Ah, I get what you are doing now. Don't think that is likely to work unless Clojure starts making IFn instances implement the right java.util.function.* interfaces. Which seems unlikely given the conservatism of Clojure development. Having said that, I do think it is possible, have been playing around with a little toy language implementation that does something similar.
I think you are better off for now writing a function or macro that allows you to wrap a Clojure function as a java.util.function.Predicate and lets you do something like: (.filter (predicate odd?)) On Tuesday, 28 July 2015 09:53:25 UTC+8, Andrew Oberstar wrote: > > 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.an...@gmail.com > <javascript:>> 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.