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.

Reply via email to