Call for Dicussion: JEP: Java Expression Trees API

Konstantin Triger kostat at gmail.com
Wed May 8 21:56:29 UTC 2024


Hi Maurizio,

Looking on this, I'm wondering how important is this case: Quoted<Function<?,
?>> f = (Integer i) -> "";
The "practical" case is something like: <T, R> RETURN_TYPE
method(Quoted<Function<T, R>> f).
Which should compile well because of inference.
And if someone insists on working with wildcards, so he has an option.

Kosta

On Wed, May 8, 2024 at 3:19 PM Maurizio Cimadamore <
maurizio.cimadamore at oracle.com> wrote:

> On 06/05/2024 18:50, Paul Sandoz wrote:
>
> Just wanted to mention that there might be alternative implementations addressing this requirement.
> 1. Structural quoting (a la C#) - derives from the variable type, e.g. Quoted<T>. So, the user understands that the lambda body will be accessible.
>
> There are some challenges with Java’s type system, which is why we embedded up where we are with the current approaches. Maurizio is better able than I to describe these challenges.
>
> Hi,
> we have explored approaches such as Quoted<T> (where T is a functional
> interface) early on. And found them a bad fit for Java. The main issue we
> faced is that being a functional interface, as per today’s JLS, is a
> predicate on class declarations not types (there was some intense
> discussion on this point during Java 8). But here we have something that
> can be treated as a functional interface or not, precisely depending on its
> type (e.g. the type parameter). E.g. a Quotable<T> is a functional
> interface or not depending on T. This is a pretty deep big departure from
> how the spec currently deal with functional interfaces.
>
> One possibility would be for the compiler/spec to ignore the Quoted<T>,
> and just focus on the inner T, and then add the quoting back, after
> type-checking. But doing so leads to (bad) edge cases. For instance, Java 8
> supports a form of inference of the target type from the explicit lambda
> parameter types, in this case:
>
> Function<?, ?> f = (Integer i) -> "";
>
> In this case, the type of the lambda expression is not just Function<?, ?>
> (the target type), but Function<Integer,Object>. That is, the compiler
> tries to get rid of the wildcards before attempting to type-check the
> lambda expression (this step is performed to avoid wildcards popping up
> when checking the lambda body). But with quoting, this won’t compose well -
> e.g.:
>
> Quoted<Function<?, ?>> f = (Integer i) -> "";
>
> Will give an error:
>
> error: incompatible types: Quoted<Function<Integer, Object>> cannot be converted to Quoted<Function<?, ?>>
>  Quoted<Function<?, ?>> f = (Integer i) -> “”;
>                                              ^
>
> That is, the functional interface type inferred by the compiler (by
> dropping wildcards) is now incompatible with the target type (because of
> the way in which generics type-argument containment rules work). To make
> things work, the client would need at least to do this:
>
> Quoted<? extends Function<?, ?>> f = (Integer i) -> “”;
>
> Overall it felt like we were pushing against the physics of the language
> here. Serializable lambdas (with all their limitations) were a strong
> precedent to build on top of, which didn’t suffer from any of the
> limitations described above.
>
> Maurizio​
>>


-- 
Regards,
Konstantin Triger
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/babylon-dev/attachments/20240509/d0073217/attachment.htm>


More information about the babylon-dev mailing list