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 
> <javascript:>> wrote:
>
>> On Sunday, 26 July 2015, Andrew Oberstar <ajobe...@gmail.com 
>> <javascript:>> 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 
>> <javascript:>
>> 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 <javascript:>
>> 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 <javascript:>.
>> 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