Call for Dicussion: JEP: Java Expression Trees API
Maurizio Cimadamore
maurizio.cimadamore at oracle.com
Wed May 8 12:18:57 UTC 2024
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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/babylon-dev/attachments/20240508/6da5b1ba/attachment.htm>
More information about the babylon-dev
mailing list