<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<font size="4"><font face="monospace">That's sort of where I was
coming from. For example, when we added
Class::getRecordComponents (which, btw, should really be a
pattern), it returns RecordComponent[] instead of
List<RecordComponent>, because that's how reflection
rolls. The benefit of using List (which are clearly "better"
than arrays) is lost by the inconsistency of "some methods
return arrays, some return lists." </font></font><br>
<br>
<div class="moz-cite-prefix">On 3/8/2023 12:05 PM, Dan Heidinga
wrote:<br>
</div>
<blockquote type="cite" cite="mid:CAJq4Gi52PYVk_Akkm3Aio33vVW3bu+uC8aSB54Zvn9f1jFqUVg@mail.gmail.com">
<div dir="ltr">
<div>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?</div>
<div><br>
</div>
<div>--Dan</div>
<br>
<div class="gmail_quote">
<div dir="ltr" class="gmail_attr">On Tue, Mar 7, 2023 at
3:16 PM Brian Goetz <<a href="mailto:brian.goetz@oracle.com" moz-do-not-send="true" class="moz-txt-link-freetext">brian.goetz@oracle.com</a>>
wrote:<br>
</div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px
0.8ex;border-left:1px solid
rgb(204,204,204);padding-left:1ex">
<div> <br>
<br>
<div>On 3/7/2023 2:51 PM, Dan Heidinga wrote:<br>
</div>
<blockquote type="cite">
<blockquote class="gmail_quote" style="margin:0px 0px
0px 0.8ex;border-left:1px solid
rgb(204,204,204);padding-left:1ex"><br>
#### Reflection<br>
<br>
Since matchers are a new kind of class member, they
will need a new kind of<br>
reflective object, and a method that is analogous to <br>
`Class::getConstructors`.<br>
The reflective object should extend `Executable`, as
all of the existing <br>
methods<br>
on `Executable` make sense for patterns (using
`Object` as the return <br>
type.) If<br>
the pattern is reflectively invoked, it returns `null`
for no match, or an<br>
`Object[]` which is the boxing of the values in the
carrier.<br>
<br>
</blockquote>
<div><br>
</div>
<div>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[]?</div>
<div><br>
</div>
<div>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.</div>
<div><br>
</div>
<div>I get it's a developer friendly approach but I
wonder if it encourages the wrong mental model about
what matchers return?</div>
<div><br>
</div>
<div>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?</div>
</blockquote>
<br>
There's a few things here, let's try to unpack them. <br>
<br>
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. <br>
<br>
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.<br>
<br>
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 <br>
<br>
Object[] match(Object matchTarget, Object...
additionalArgs)<br>
<br>
where match failure is reflected as null.<br>
<br>
This also nudges me a bit towards hiding matchers from
getMethods() and friends (as we do with constructors). <br>
<br>
<blockquote type="cite">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?</blockquote>
<br>
I had been assuming that we would use
MethodHandle::findStatic for this. <br>
<br>
<blockquote type="cite">
<div> </div>
<blockquote class="gmail_quote" style="margin:0px 0px
0px 0.8ex;border-left:1px solid
rgb(204,204,204);padding-left:1ex"> We will then need
some additional methods to describe the bindings, so
the<br>
subtype of `Executable` has methods like
`getBindings`, <br>
`getAnnotatedBindings`,<br>
`getGenericBindings`, `isDeconstructor`, `isPartial`,
etc. These <br>
methods will<br>
decode the `Matcher` attribute and its embedded
attributes.<br>
</blockquote>
<div><br>
</div>
<div>What does `getBindings` return? The MethodType
describing the bindings? A Class[] describing the
types of the bindings? Something else?</div>
<br>
</blockquote>
<br>
Class[] getBindings();<br>
Type[] getGenericBindings();<br>
AnnotatedType[] getAnnotatedBindings();<br>
<br>
<br>
<br>
</div>
</blockquote>
</div>
</div>
</blockquote>
<br>
</body>
</html>