Improving Method Reference Ergonomics

Peter Eastham petereastham at gmail.com
Mon Dec 9 17:30:15 UTC 2024


Hey Brian,

I'm hesitant to respond further, as I'd like some time to do a proper write
up that can provide a more solid context for discussion than my simple
example provided.

You are right in that "createQuery(Customer::new)" would be behaving around
the Constructor, instead of utilizing it as a "Supplier<Customer>". The
exact type this would use is not something I have fully considered, and I
agree that the current Functional Interfaces aren't sharp enough to
restrict it to only Method References. It's also not a solution to have
Method References resolve to their own type without being able to still
work in those situations.

When you say Dynamic Failure, can you explain that a bit more? My
assumption is that there it would be an issue if you dynamically transform
the class, specifically the method in the reference. However I'm unsure if
that is any different of a failure than if you did the same with the
current use case.

Thanks,
-Peter

On Mon, Dec 9, 2024 at 8:56 AM Brian Goetz <brian.goetz at oracle.com> wrote:

> By "greater access", I think you mean "if they could be reflected on as a
> function, not just a thunk of behavior", yes?  Then
> `createQuery(Customer::new)` would be able to reflect over the constructor
> reference and see "oh, it's a constructor for Customer".
>
> We've given a good deal of thought to this problem, but it's messy for a
> number of reasons, including erasure and limitations on the static type
> system.  Does createQuery mean to limit to method references, rather than
> all lambdas?  If so, then Supplier<T> is not a sharp enough type, and users
> could pass a Supplier that ends up causing a dynamic failure.  If not, then
> it sounds like what you want is to reflect over the concrete shape of the
> supplier, which runs into erasure problems (among others -- what if you
> intended a Supplier<Foo>, but the lambda you passed instantiates a
> Supplier<SubtypeOfFoo> where the subtype is inaccessible to the
> framework.)
>
> So while it is possible to associate more metadata with method references
> than we currently do, and we've considered it, most of the obvious paths
> run into obvious roadblocks just a bit farther down the road.
>
>
>
>
> On 12/8/2024 8:52 PM, Peter Eastham wrote:
>
> Hi Amber team,
>
> Earlier this week I was playing around with fluent API design, and I
> believe Java could benefit from some improvements to the usage of Method
> References, I'll keep this short with the following example.
>
> Lets take the following JPA Criteria from section 6.3.3 of the
> Specification, (Only for an example of what an API could begin doing, not
> should do)
> CriteriaQuery q = cb.createQuery(Customer.class);
> Root customer = q.from(Customer.class);
> Join order = customer.join(Customer_.orders, JoinType.LEFT);
> q.where(cb.equal(customer.get(Customer_.status), 1)).select(customer);
>
> If there was greater access to the Method Reference more implicit
> information could be passed, reducing the noise,
> CriteriaQuery q = CriteriaQuery.createQuery(Customer::new)
>   .leftJoin(Customer::orders)
>   .where(Object::equals, Customer::status, 1);
> var result = q.select();
>
> Regarding what should be available, the resolved Class and Method name at
> least, anything else I'd leave up to the feasibility of the change.
>
> Thanks,
> -Peter
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-dev/attachments/20241209/4e89fcad/attachment-0001.htm>


More information about the amber-dev mailing list