> > Which seems unlikely given the conservatism of Clojure development.
More than that, it would mean that Clojure required Java 8. On 28 July 2015 at 05:23, Mikera <mike.r.anderson...@gmail.com> wrote: > 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> 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. > -- 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.