<!DOCTYPE html><html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body><div style="font-family: sans-serif;"><div class="markdown" style="white-space: normal;">
<p dir="auto">On 1 Jun 2023, at 11:30, Dan Smith wrote:</p>
</div><div class="plaintext" style="white-space: normal;"><blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; color: #777777;"><blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; border-left-color: #999999; color: #999999;"><p dir="auto">On Jun 1, 2023, at 10:59 AM, Brian Goetz <brian.goetz@oracle.com> wrote:</p>
<p dir="auto">I think that there should be an explicit (and not synthetic) method_info for the implicit constructor, with the obvious Code attribute (`defaultvalue` / `areturn`.)</p>
<p dir="auto">My rationale is: "the declaration said there's a no-arg constructor, I should be able to call it". And that intuition is entirely reasonable. Users should be able to say `new Complex()` and get a default complex value. (Maybe they can also say `Complex.default`; maybe we won't need that.) And the same for reflection.</p>
</blockquote></blockquote></div>
<div class="markdown" style="white-space: normal;">
<p dir="auto">I like this. A non-Java language might omit such a method from its classfile, or even give it a different body. (A non-Java language might use such a body for some language-specific purpose. That’s up to the translation strategy of that other language.) For Java, the constructor will either not exist or will always have the given two-instruction body. It will never have a body of explicitly user-written statements.</p>
</div><div class="plaintext" style="white-space: normal;"><blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; color: #777777;"><blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; border-left-color: #999999; color: #999999;"><p dir="auto">Also, in case it is not obvious, the following class is illegal:</p>
<p dir="auto"> value class X {
<br>
implicit X();
<br>
X() { ... }
<br>
}</p>
<p dir="auto">because it is trying to declare the same constructor twice. An implicit constructor is a constructor, just one for which the compiler can deduce specific known semantics.</p>
</blockquote></blockquote></div>
<div class="markdown" style="white-space: normal;">
<p dir="auto">That all hangs together well.</p>
<p dir="auto">It allows <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;">new C()</code> to be a valid expression with a regular translation (as a call to <vnew>). We could “optimize” <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;">new C()</code> to <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;">defaultvalue</code>, but why bother? If we keep it as <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;">invokestatic <vnew></code> then JVMTI has something to work with; you can put breakpoints on the implicit constructor.</p>
<p dir="auto">(No, those breakpoints won’t fire for implicit construction, such as in a flat field or array element. But they will fire for explicit <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;">new C()</code>.)</p>
</div><div class="plaintext" style="white-space: normal;"><blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; color: #777777;"><p dir="auto">Agree with all of this. Some of these details were initially unclear a few weeks ago, but I think we've settled on a design in which the implicit constructor is a "real", invokable constructor, in addition to signaling some metadata about the class.</p>
<blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; border-left-color: #999999; color: #999999;"><p dir="auto">On 6/1/2023 10:47 AM, Dan Heidinga wrote:</p>
<blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; border-left-color: #BBBBBB; color: #BBBBBB;"><p dir="auto">Alas representing implicit constructors with a `method_info` is not without costs: primarily specing how the method_info exists and explaining why it doesn't have a code attribute.</p>
</blockquote></blockquote><p dir="auto">There would be nothing special about the <vnew> method. It only exists as a code path for explicit constructor invocations. The "I have a default instance" metadata comes from ImplicitCreation.</p>
</blockquote></div>
<div class="markdown" style="white-space: normal;">
<p dir="auto">Yes. Except, I’d like to note a subtle issue here: All value classes “have” default values, because the <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;">aconst_default</code> bytecode works for all value classes. (Otherwise, there would be no primordial value to start from in <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;"><vnew></code> methods.)</p>
<p dir="auto">I’d prefer to say this, probably not for the JLS, but for the JVMS: For some value types, the default values are private and for some they are public. (There are no intermediate access levels; we tried that and it was horrible.) What the JLS calls a missing default value the JVMS calls a private default value. This is necessary whenever we write about translation strategies. A private default value (invisible in the JLS) can have a rather rich career in the bytecodes of the JVMS.</p>
<p dir="auto">I think I’m on record as saying that both <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;">aconst_default</code> and <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;">withfield</code> should be private to the nest of the declared value class they operate within. Their use will initially be confined to constructors generated statically by a Java translation strategy. But in the future, with “with” statements or serialization frameworks, it will be useful to support those instructions at other places in the nest, including in dynamically injected nestmates. The JVM already knows how to make privacy checks; we should have the resolution of those instructions include the same privacy check, rather than some new ad hoc check.</p>
</div><div class="plaintext" style="white-space: normal;"><blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; color: #777777;"><p dir="auto">(Do we expect reflection to reconstruct ImplicitCreation+no-arg <vnew> --> 'Constructor.isImplicit' or 'ACC_IMPLICIT'? Maybe. Not entirely sure yet what the reflection surface will look like.)</p>
</blockquote></div>
<div class="markdown" style="white-space: normal;">
<p dir="auto">Perhaps ACC_MANDATED applies here, to the implicit constructor? I guess not; but it has some of the feel of a mandated parameter, which is not present in the code but visible reflectively.</p>
<p dir="auto">Then again, an implicit constructor <em>IS</em> visible in the code, though abbreviated. Kind of like a canonical constructor of a record is visible, though abbreviated.</p>
<p dir="auto">In any case, since Java won’t allow nullary ctors of value types to have arbitrary code, it’s a safe bet that if you reflect a value class and see a nullary ctor, it’s implicit. What else could it be?</p>
</div></div></body>
</html>