<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Fri, Mar 16, 2018 at 3:09 PM, 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">
  
    
  
  <div text="#000000" bgcolor="#FFFFFF"><span class=""><div class="m_3848697546723567125moz-cite-prefix">On 3/16/2018 5:59 PM, Kevin Bourrillion
      wrote:<br>
    </div>
    <blockquote type="cite">
      <div dir="ltr">
        <div class="gmail_extra">
          <div class="gmail_quote">On Fri, Mar 16, 2018 at 2:28 PM,
            Brian Goetz <span dir="ltr"><<a href="mailto:brian.goetz@oracle.com" target="_blank">brian.goetz@oracle.com</a>></span>
            wrote:<br>
            <blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
              <div text="#000000" bgcolor="#FFFFFF"><br>
                But also, there are times when matching against the
                abstract type makes sense too.  For example, if you want
                to traverse the tree and perform structural operations
                (say, detect if a tree contains a reference to the
                variable "x"), matching on abstract records is pretty
                useful:<br>
                <br>
                    boolean containsVar(Node node, String name) {<br>
                        return switch (node) {<br>
                            case VarNode(String s) -> s.equals(name);<br>
                            case BinOpNode(var left, var right) ->
                containsVar(left, name) || containsVar(right, name);<br>
                            default -> false;<br>
                        }<br>
                    }<br>
              </div>
            </blockquote>
            <div><br>
            </div>
            <div>Am I correct that if BinOpNode is an interface there
              will be a way for it to specify how it destructures so
              that it can get this effect also - and it's just that
              records are neat because they know how to destructure for
              free?</div>
          </div>
        </div>
      </div>
    </blockquote>
    <br></span>
    Destructuring for free is important, but it's not just destructuring
    -- it's all the stuff.  It means that the fields and accessors (and
    therefore, any methods derivable from that state that is common to
    all subtypes) get pulled into the abstract record too.  Remember,
    records can have behavior that is derived from their state.  So if
    there is any behavior that is natural on a BinaryOpNode, to put it
    there, it needs to have its state (or at least state accessors)
    there.  <br></div></blockquote><div><br></div><div>Sure, I was assuming you have to put the accessors explicitly on the BinOpNode interface, which is a bit more cumbersome than getting to use record syntax, but only a bit. What else will go wrong? Note: I've been curious what explicit destructuring is expected to look like.</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div text="#000000" bgcolor="#FFFFFF"><span class=""><blockquote type="cite"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div>We want people to be solid on the fact that two records
              with all the same field values are always equals(), and
              then they may apply that view to an abstract record type
              where it doesn't hold true.</div>
          </div>
        </div>
      </div>
    </blockquote>
    </span>equals() on abstract records is abstract; only the concrete record
    gets to declare equals.  <br></div></blockquote><div><br></div><div><i>Eppur si muove...</i> what I mean is, nevertheless equals() is usable and will sometimes return a `false` that may be surprising. Yeah, it's not fundamentally different from the `Collection` problem, and yeah, I do think we can probably live with it; it's just not "free".</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"><div text="#000000" bgcolor="#FFFFFF"><span class=""><blockquote type="cite"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div text="#000000" bgcolor="#FFFFFF">Pretend we already had non-final.  Does that
              change your inclination?</div>
            <div><br>
            </div>
            <div>I don't think so? The reversed default behavior feels
              like arbitrary difference from regular fields (again, I do
              <i>want</i> to encourage finalness of record fields...).
              Would we permit the "not final" keyword on interface
              fields too? <br>
            </div>
          </div>
        </div>
      </div>
    </blockquote>
    <br></span>
    Hadn't thought about that, but, assuming we didn't think that was a
    bad idea, yes, we surely could do that.  (In other words; interface
    fields should be final because we think its dumb for them to be
    mutable, not because we don't have a way to spell it.)  <br></div></blockquote><div><br></div><div>Hadn't thought about it either. I decided to think about it just now and, oh, it's a completely <i>disgusting</i> idea, because it'd still be implicitly static, mutable statics are The Worst, plus you could modify it from default methods without even realizing it's not instance state.</div><div><br></div><div>So add all this up and we have <i>three</i> kind of finalness for fields:</div><div><br></div><div>- by default mutable, but you can change it</div><div>- by default final, and you can't change it</div><div>- (and now) by default final, but you can change it</div><div><br></div><div>This seems like quite a bad situation to me.</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"><div text="#000000" bgcolor="#FFFFFF">
    <br>
    I am usually wary of "let's flip the default on this new thing
    because we can" arguments.  This seems one of the few places where
    we could really get away with it, so I want to consider it
    seriously.  If we think its a bad idea, I'm OK with ultimately
    saying "nah, its like classes."  But I don't want to skip over that
    deliberation, and certainly not for a silly reason like "but we
    can't spell it"!  <br><span class="">
    <br>
    <blockquote type="cite">
      <div dir="ltr">
        <div class="gmail_extra">
          <div class="gmail_quote">
            <div text="#000000" bgcolor="#FFFFFF"><span></span>OK, but
              do  you have an opinion on whether records should
              automatically acquire a clone() implementation?  <br>
            </div>
            <div><br>
            </div>
            <div>As much as possible we'll encourage all-final,
              array-free records that have no need to be cloned, but
              some number of records will go against that, and I guess
              it's better that they have clone() than that they don't.
              But my concern is: What does it do -- deep-clone arrays
              but shallow-clone everything else? Sounds problematic no
              matter which way you decide it.<br class="m_3848697546723567125gmail-Apple-interchange-newline">
            </div>
          </div>
          <br>
        </div>
      </div>
    </blockquote></span>
    Yes, that's the question.  One possibility is just to always clone
    shallowly; this is not as dumb as it sounds, since the fields are
    already exposed for read, and therefore any deep mutability is
    already flapping in the wind.  <br></div></blockquote><div><br></div><div>Okay, I guess that's the right move because you kinda want `record.clone().equals(record)`. But a user's assumption that `record.clone()` would deep-clone the array might be the entire reason they're using clone() at all. Oh well, it's not like we'd be making arrays awful for the first time.</div><div><br></div></div><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>