<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Fri, Mar 16, 2018 at 11:55 AM, Brian Goetz <span dir="ltr"><<a href="mailto:brian.goetz@oracle.com" target="_blank">brian.goetz@oracle.com</a>></span> wrote:</div><div class="gmail_quote"><br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">There are a number of potentially open details on the design for records.  My inclination is to start with the simplest thing that preserves the flexibility and expectations we want, and consider opening up later as necessary.<br>
<br>
One of the biggest issues, which Kevin raised as a must-address issue, is having sufficient support for precondition validation. Without foreclosing on the ability to do more later with declarative guards, I think the recent construction proposal meets the requirement for lightweight enforcement with minimal or no duplication.  I'm hopeful that this bit is "there".<br></blockquote><div><br></div><div>Agreed. Even if we had solved declarative guards, we'd still benefit from what you're doing here when we need a defensive copy etc.</div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Our goal all along has been to define records as being “just macros” for a finer-grained set of features.  Some of these are motivated by boilerplate; some are motivated by semantics (coupling semantics of API elements to state.)  In general, records will get there first, and then ordinary classes will get the more general feature, but the default answer for "can you relax records, so I can use it in this case that almost but doesn't quite fit" should be "no, but there will probably be a feature coming that makes that class simpler, wait for that."<br>
<br>
<br>
Some other open issues (please see my writeup at <a href="http://cr.openjdk.java.net/~briangoetz/amber/datum.html" rel="noreferrer" target="_blank">http://cr.openjdk.java.net/~br<wbr>iangoetz/amber/datum.html</a> for reference), and my current thoughts on these, are outlined below. Comments welcome!<br>
<br>
 - Extension.  The proposal outlines a notion of abstract record, which provides a "width subtyped" hierarchy.  Some have questioned whether this carries its weight, especially given how Scala doesn't support case-to-case extension (some see this as a bug, others as an existence proof.)  Records can implement interfaces.<br></blockquote><div><br></div><div>I also suggest we avoid abstract records. A reference to one may seem like a proper record but it will behave badly with regard to equals(). I don't see the upside compared to a common interface, and then you don't have to have the novel parameterized extends clause.</div><div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
 - Concrete records are final.  Relaxing this adds complexity to the equality story; I'm not seeing good reasons to do so.<br></blockquote><div><br></div><div>Absolutely.</div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"> - Additional instance fields.  These are a much bigger concern. While the primary arguments against them are of the "slippery slope" variety, I still have deep misgivings about supporting unrestricted non-principal instance fields, and I also haven't found a reasonable set of restrictions that makes this less risky.  I'd like to keep looking for a better story here, before just caving on this, as I worry doing so will end up biting us in the back.<br></blockquote><div><br></div><div>Lazy-initialized derived values are common enough. I'm not grasping what there is to be afraid of here - <span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline">I thought that preventing custom eq/hc addressed the concerns. I understand the spirit of "start restrictive and open up later", but I think we should still have some halfway convincing explanation of why this was worth worrying about.</span></div><div><br></div><div> <br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"> - Mutability and accessibility.  I'd like to propose an odd choice here, which is: fields are final and package (protected for abstract records) by default, but finality can be explicitly opted out of (non-final) and accessibility can be explicitly widened (public).<br></blockquote><div><br></div><div>I agree that field accessibility should play by the normal rules.</div><div><br></div><div>On the other hand. As much as I want everyone to stick to immutable records as much as possible, it seems very costly to me to have to introduce a new keyword for "not final", and have users keep track of which things have which defaults. Let this just be "best practice", like it already is for regular fields (make them final unless you have good reason not to).</div><div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"> - Accessors.  Perhaps the most controversial aspect is that records are inherently transparent to read; if something wants to truly encapsulate state, it's not a record.  Records will eventually have pattern deconstructors, which will expose their state, so we should go out of the gate with the equivalent.  The obvious choice is to expose read accessors automatically.  (These will not be named getXxx; we are not burning the ill-advised Javabean naming conventions into the language, no matter how much people think it already is.)  The obvious naming choice for these accessors is fieldName().  No provision for write accessors; that's bring-your-own.<br></blockquote><div><br></div><div>Method and field named identically is a slight concern. If we gain field references using the same syntax as method references there would probably be no way to refer to such a field. I'm pretty sure this is not worth worrying about though.</div><div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"> - Core methods.  Records will get equals, hashCode, and toString.  There's a good argument for making equals/hashCode final (so they can't be explicitly redeclared); this gives us stronger preservation of the data invariants that allow us to safely and mechanically snapshot / serialize / marshal (we'd definitely want this if we ever allowed additional instance fields.)  No reason to suppress override of toString, though.</blockquote><div><br></div><div>Agree with all this.</div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Records could be safely made cloneable() with automatic support too (like arrays), but not clear if this is worth it (its darn useful for arrays, though.)<br></blockquote><div><br></div><div>People just really need to not use arrays anymore, and especially not with records. imho we should have added immutable List and ImmutableIntArray etc. classes a very long time ago. I know we won't now due to our value type aspirations. In the meantime we're in a weird place. Arrays are completely terrible except as micro-optimizations to be used with great care.</div></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature" data-smartmail="gmail_signature"><div dir="ltr"><div><div dir="ltr"><div><div dir="ltr"><div style="line-height:1.5em;padding-top:10px;margin-top:10px;color:rgb(85,85,85);font-family:sans-serif"><span style="border-width:2px 0px 0px;border-style:solid;border-color:rgb(213,15,37);padding-top:2px;margin-top:2px">Kevin Bourrillion |</span><span style="border-width:2px 0px 0px;border-style:solid;border-color:rgb(51,105,232);padding-top:2px;margin-top:2px"> Java Librarian |</span><span style="border-width:2px 0px 0px;border-style:solid;border-color:rgb(0,153,57);padding-top:2px;margin-top:2px"> Google, Inc. |</span><span style="border-width:2px 0px 0px;border-style:solid;border-color:rgb(238,178,17);padding-top:2px;margin-top:2px"> <a href="mailto:kevinb@google.com" target="_blank">kevinb@google.com</a></span></div></div></div></div></div></div></div>
</div></div>