Revisiting field references
brian.goetz at oracle.com
Wed Jun 5 13:30:23 UTC 2019
More random comments.
> Getter as Supplier
It is worth asking whether bound field refs are worth it at all. On the one hand, they make perfect sense from a type-system perspective, but on the other, I’m struggling to thing of real-world use cases where they pay for themselves (vs a lambda like () -> holder.field). Bound method refs are the least commonly used kind of method refs, and I would think bound fields would be even less useful. On the other other hand, the asymmetry might seem glaring.
On the subject of whether the Foo::m syntax has enough juice to get all the way there, let’s keep in mind that there’s a new kind of class member coming down the road — patterns — and “pattern reference” might want to eventually join this party. (Another precedent we can lean on for field ref syntax is the one we use for class literals — Foo.class. This is less pretty but clearly more extensible to other kinds of members.).
Starting from where we are now, there are a number of (mostly orthogonal!) directions we can branch into:
- Explicit method refs. This is a method ref with explicit type parameters (Foo::m(int, int)); it is marginally useful for disambiguation today, but an enabler for other features on this list (such as alternate target types, or standalone method refs.).
- Alternate target types. Currently a method ref can be converted only to a SAM type; conversion to j.l.r.Method is potentially useful.
- Sharper method refs. Adding in a MethodRef interface that carries symbolic information about the method ref; when converting a mref to a SAM type, we’d get an object of type (SAM & MethodRef).
- Better equals/toString for method refs vs lambdas.
- Standalone types. This would give an exact method ref a standalone type of MethodRef.
- Usability in annotations.
- Abbreviated member refs (::m).
- Generalized syntax. If we choose to keep going with ::, we’ll have to face down the ambiguities, which likely means a way to disambiguate. Clearly we can disambiguate in the direction of methods with explicit parameter types, but how do we disambiguate in the direction of fields (or patterns)? Perhaps (just throwing out a dumb idea for sake of exposition), the method ref Foo::m is really shorthand for Foo::method::m, where the “method” is inferred most of the time.
I realize tackling these all at once is overwhelming, but having a full map of the design space is likely to be helpful in identifying interactions and directions of highest leverage.
More information about the amber-spec-observers