Deconstructor reflection Was: Re: Deconstruction patterns
Dan Heidinga
heidinga at redhat.com
Wed Mar 8 17:05:20 UTC 2023
Thanks for the response. This seems reasonable though I still have an
aversion to the Object[] return type for the `match` method though it fits
with the way reflection works today. I hate wasting the Carrier runtime's
benefits by immediately boxing and collecting to the array for reflection
but maybe anything else is trying to fix the sins of the past?
--Dan
On Tue, Mar 7, 2023 at 3:16 PM Brian Goetz <brian.goetz at oracle.com> wrote:
>
>
> On 3/7/2023 2:51 PM, Dan Heidinga wrote:
>
>
>> #### Reflection
>>
>> Since matchers are a new kind of class member, they will need a new kind
>> of
>> reflective object, and a method that is analogous to
>> `Class::getConstructors`.
>> The reflective object should extend `Executable`, as all of the existing
>> methods
>> on `Executable` make sense for patterns (using `Object` as the return
>> type.) If
>> the pattern is reflectively invoked, it returns `null` for no match, or an
>> `Object[]` which is the boxing of the values in the carrier.
>>
>>
> This surprised me slightly and I'm not sure I follow the reasoning on why
> the return value would be boxed and collected into an Object[]?
>
> The design says matcher methods return Object as an opaque descriptor for
> the actual implementation carrier object. Yet, reflection will take that
> carrier object, and replace it with an equivalent Object[] resulting in
> more allocations and (potentially) boxing on the return path.
>
> I get it's a developer friendly approach but I wonder if it encourages the
> wrong mental model about what matchers return?
>
> Would it make sense to add an extra step in that process so the
> java.lang.reflect.Matcher instance has a `Object[] resultToArray(Object)`
> method? It's more ceremony (yuck) but allows avoiding the array creation
> and maybe the boxing on the return path for allocation-sensitive callers?
>
>
> There's a few things here, let's try to unpack them.
>
> I agree that the actual classfile descriptor of the synthetic method need
> not be all that related to what reflection does, though it is nice to
> minimize that difference if we can.
>
> Reflection routinely boxes everything; if you're working reflectively,
> this is just the price of entry? MethodHandles are a different story, of
> course, and we should be able to unreflect a Matcher to something that can
> be invoked directly.
>
> I had been assuming that `invoke` was a method on Executable, but now that
> I look, I realize that invocation lives on the subclasses Method and
> Constructor. So we have more latitude than I thought. Which nudges me a
> little towards
>
> Object[] match(Object matchTarget, Object... additionalArgs)
>
> where match failure is reflected as null.
>
> This also nudges me a bit towards hiding matchers from getMethods() and
> friends (as we do with constructors).
>
> And speaking of MethodHandles, will there be new
> MethodHandles.Lookup.findMatcher , findDeconstructor, etc methods? Or do
> you see them being looked up with the existing find* methods?
>
>
> I had been assuming that we would use MethodHandle::findStatic for this.
>
>
>
>> We will then need some additional methods to describe the bindings, so the
>> subtype of `Executable` has methods like `getBindings`,
>> `getAnnotatedBindings`,
>> `getGenericBindings`, `isDeconstructor`, `isPartial`, etc. These
>> methods will
>> decode the `Matcher` attribute and its embedded attributes.
>>
>
> What does `getBindings` return? The MethodType describing the bindings?
> A Class[] describing the types of the bindings? Something else?
>
>
> Class[] getBindings();
> Type[] getGenericBindings();
> AnnotatedType[] getAnnotatedBindings();
>
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-spec-experts/attachments/20230308/da92c8f4/attachment.htm>
More information about the amber-spec-experts
mailing list