<div dir="auto"><div>Thanks for the response <span class="gmail_chip gmail_plusreply" dir="auto"><a href="mailto:attila.kelemen85@gmail.com" style="color:#15c;text-decoration:underline">@Attila Kelemen</a></span>.<div dir="auto"><br></div><div dir="auto">Yes, I am definitely not married to the concept of using an enum or an inner class. There are clear flaws with it, and I only use it to explain what I really want.</div><div dir="auto"><br></div><div dir="auto">Really, all I want is to be able to enumerate the components of a record and also get exhaustiveness checking.</div><div dir="auto"><br></div><div dir="auto">As for your implementation suggestion, no real comments. As long as it works, I am fine with any implementation.</div><br><br><div class="gmail_quote gmail_quote_container"><div dir="ltr" class="gmail_attr">On Mon, Dec 1, 2025, 1:10 PM Attila Kelemen <<a href="mailto:attila.kelemen85@gmail.com">attila.kelemen85@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Hi,<div><br></div><div>My concern with the actual proposal (not with the problem it is trying to solve) is that it doesn't generalize well. That is, imagine if function types get added to the language with support to query the parameters, etc. of the underlying function. Then immediately this change becomes a useless (in fact, harmful) noise.</div><div><br></div><div>So, let me give a counter proposal (even though I'm quite certain it will not be added anytime soon given all the important stuff in the queue):</div><div><br></div><div>Allow the following construct:</div><div><br></div><div>```</div><div>RecordComponentAccessor accessor = MyRecord::myComponent;</div><div>```</div><div><br></div><div>where the `RecordComponentAccessor` could look like it (of course, doesn't have to be an interface):</div><div><br></div><div>```</div><div>interface RecordComponentAccessor<R, V> {<br>  Type recordType();<br>  Class<? extends R> recordRawType();<br><br>  String componentName();<br><br>  Type componentType();<br>  Class<?> componentRawType();<br><br>  MethodHandle getter();<br><br>  default V getValue(R record) {<br>     // TODO: Deal with `throws Throwable`<br>    return getter().invoke(record);<br>  }<br>}<br></div><div>```</div><div><br></div><div>The benefit of this is that, if function types ever become a thing, then of course this can be retrofitted to implement (or extend) the function type `(R) -> V` (or whatever notation it would have), which would likely have more generic methods like `List<Class<?>> parameterRawTypes()`, etc.</div><div><br></div><div>In my opinion, this is not harder to implement than the original proposal, and more future proof. And if it is only implemented for records, then no massive changes to the JVM needed (unlike with the introduction of a full blown function type).</div><div><br></div><div>Attila</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">David Alayachew <<a href="mailto:davidalayachew@gmail.com" target="_blank" rel="noreferrer">davidalayachew@gmail.com</a>> ezt írta (időpont: 2025. nov. 30., V, 22:51):<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 dir="ltr"><div class="gmail_default" style="font-family:monospace">Hello <a class="gmail_plusreply" id="m_-8429801928841104067m_-372327463507508991plusReplyChip-0" href="mailto:amber-dev@openjdk.org" target="_blank" rel="noreferrer">@amber-dev</a>,</div><div class="gmail_default" style="font-family:monospace"><br></div><div class="gmail_default" style="font-family:monospace">(this is a follow-up from the previous thread -- <a href="https://mail.openjdk.org/pipermail/amber-dev/2025-November/009472.html" target="_blank" rel="noreferrer">https://mail.openjdk.org/pipermail/amber-dev/2025-November/009472.html</a>)</div><div class="gmail_default" style="font-family:monospace"><br></div><div class="gmail_default" style="font-family:monospace">Since records are <b><i>transparent</i></b> carriers of data, then that means that all of the record components are known at compile time and visible to all consumers who can reach the record itself.</div><div class="gmail_default" style="font-family:monospace"><br></div><div class="gmail_default" style="font-family:monospace">Right now, the only way to reach these record components is by drilling down via j.l.Class ---> j.l.r.RecordComponent. And even then, you are forced into doing String comparison against what you <b><i><u>expect</u></i></b> the record component to be named. That means that you will get a runtime error, not a compile time error, if a record component changes names.</div><div class="gmail_default" style="font-family:monospace"><br></div><div class="gmail_default" style="font-family:monospace">I propose that we enumerate the Record Components of a record.</div><div class="gmail_default" style="font-family:monospace"><br></div><div class="gmail_default" style="font-family:monospace">My naive way of accomplishing this would be to literally provide each record with its own inner enum, each value corresponding to the respective record component on a record.</div><div class="gmail_default" style="font-family:monospace"><br></div><div class="gmail_default" style="font-family:monospace">Consider the following record.</div><div class="gmail_default" style="font-family:monospace"><br></div><div class="gmail_default" style="font-family:monospace">record User(String firstName, String lastName, int age) {}</div><div class="gmail_default" style="font-family:monospace"><br></div><div class="gmail_default" style="font-family:monospace">I ask that record get access to its own inner enum (let's call it VALUES), that can be referenced. Like this.</div><div class="gmail_default" style="font-family:monospace"><br></div><div><div style="font-family:monospace" class="gmail_default">record User(String firstName, String lastName, int age)<br>{<br>    enum Values {<br>        firstName,<br>        lastName,<br>        age,<br>        ;<br>        public final java.lang.reflect.RecordComponent recordComponent =<br>                Arrays<br>                    .stream(User.class.getRecordComponents())<br>                    .filter(rc -> rc.getName().equals(<a href="http://this.name" target="_blank" rel="noreferrer">this.name</a>()))<br>                    .findAny()<br>                    .orElseThrow()<br>                    ;<br>    }<br>}<br></div><br></div><div><div style="font-family:monospace" class="gmail_default">This is better than the current situation for all sorts of reasons.</div><div style="font-family:monospace" class="gmail_default"><ol><li>Currently, if I want a RecordComponent, I must make a String-comparison. I lose compile time safety of checking if my hard-coded string no longer matches because someone changed the record.</li><li>I now get exhaustiveness checking, which really should have been there from the beginning.</li></ol><div>And of course, I am not tied to the idea of using an enum or an inner class. My real goal is to be able to enumerate over the components of a record. Not even necessarily over the j.l.r.RecordComponents of a record. Whatever form that takes is fine with me.</div><div><br></div><div>But not being able to enumerate over a records components (obviously, in a type-safe, non-<b><u><i>stringly</i></u></b>-typed way) is making records less powerful for seemingly no reason. The contract and spec enables it, it's just not being utilized.</div><div><br></div><div>Thank you for your time and consideration.</div><div>David Alayachew</div></div></div></div>
</blockquote></div>
</blockquote></div></div></div>