<html>
  <head>

    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    <div class="markdown-here-wrapper" data-md-url="Thunderbird"
      style="">
      <p style="margin: 0px 0px 1.2em !important;">If we expect values
        to “work like an int”, then <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">==</code>
        comparisons on value types should work like they do on
        primitives:</p>
      <pre style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;font-size: 1em; line-height: 1.2em;margin: 1.2em 0px;"><code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;white-space: pre; overflow: auto; border-radius: 3px; border: 1px solid rgb(204, 204, 204); padding: 0.5em 0.7em; display: block !important;">value class Point { ... }

... client code ...

/* mutable */
Point location;

void setLocation(Point p) {
    if (p != location) {
        fireExpensivePropertyChangeEvent(location, p);
        this.location = p;
    }
}
</code></pre>
      <p style="margin: 0px 0px 1.2em !important;">Users will reasonably
        expect this idiom to work, just as they would for <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">int</code>
        properties. </p>
      <p style="margin: 0px 0px 1.2em !important;">There have been at
        least four suggested treatments of <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">val==</code>:</p>
      <ul style="margin: 1.2em 0px;padding-left: 2em;">
        <li style="margin: 0.5em 0px;">Illegal; compilation error</li>
        <li style="margin: 0.5em 0px;">Always false; user must follow up
          with <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">.equals()</code>
          test</li>
        <li style="margin: 0.5em 0px;">Substitutibility test — are these
          the same value</li>
        <li style="margin: 0.5em 0px;">Delegate to <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">.equals()</code>
          (call this “deep substitutibility”)</li>
      </ul>
      <p style="margin: 0px 0px 1.2em !important;">I think the first is
        unreasonable and should be discarded, based on the above
        illustration of failure to “work like an int”; I think the
        second is the same. </p>
      <p style="margin: 0px 0px 1.2em !important;">We expect generic
        code to use the LIFE idiom:</p>
      <pre style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;font-size: 1em; line-height: 1.2em;margin: 1.2em 0px;"><code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;white-space: pre; overflow: auto; border-radius: 3px; border: 1px solid rgb(204, 204, 204); padding: 0.5em 0.7em; display: block !important;">(x == y) || x.equals(y)
</code></pre>
      <p style="margin: 0px 0px 1.2em !important;">The LIFE idiom arose
        because <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">ref==</code>
        is fast, and so we can optimize away the potentially expensive <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">.equals()</code>
        call when called with identical objects. But, if the <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">val==</code>
        test becomes more expensive, then what started out as an
        optimization, might lead to duplication of nontrivial work,
        because the <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">.equals()</code>
        implementation may well also have an <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">==</code>
        test. But, we don’t want to let the optimization tail wag the
        dog here. </p>
      <p style="margin: 0px 0px 1.2em !important;">Separately, we have
        been reluctant to push value substitutibility into <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">acmp</code>,
        for fear of perturbing the performance model there. So, let’s
        posit a <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">vcmp</code>,
        a sibling to <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">{ildf}cmp</code>,
        and translate <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">val==</code>
        to that, and let <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">acmp</code>
        continue to return false when either operand is a value. </p>
      <p style="margin: 0px 0px 1.2em !important;">Now, for pure value
        code, like the above, we translate <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">val==</code>
        to <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">vcmp</code>,
        and we work like an int. And for generic code, the LIFE idiom:</p>
      <pre style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;font-size: 1em; line-height: 1.2em;margin: 1.2em 0px;"><code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;white-space: pre; overflow: auto; border-radius: 3px; border: 1px solid rgb(204, 204, 204); padding: 0.5em 0.7em; display: block !important;">x == y || x.equals(y)
</code></pre>
      <p style="margin: 0px 0px 1.2em !important;">(when <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">x</code>
        and <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">y</code>
        are of type <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">T</code>)
        translates to an <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">acmp</code>
        backed up by an <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">invokevirtual</code>,
        and when <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">T</code>
        is specialized to a value, the <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">acmp</code>
        is fast and always false, and when specialized to a reference,
        is fast and computes <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">ref==</code>.
        I believe this gives everyone what they want:</p>
      <ul style="margin: 1.2em 0px;padding-left: 2em;">
        <li style="margin: 0.5em 0px;">value equality is intuitive and
          appropriately fast</li>
        <li style="margin: 0.5em 0px;">Existing generics continue using
          LIFE, and get fast (enough) translation both for reference and
          value instantiations</li>
        <li style="margin: 0.5em 0px;">Generic code that forgets <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">.equals()</code>
          is equally wrong for reference and value instantiations</li>
        <li style="margin: 0.5em 0px;">Generic code that goes straight
          to <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">.equals()</code>
          works correctly for reference and value instantiation</li>
      </ul>
      <div
title="MDH:PHR0PklmIHdlIGV4cGVjdCB2YWx1ZXMgdG8gIndvcmsgbGlrZSBhbiBpbnQiLCB0aGVuIGA9PWAg&#xA;Y29tcGFyaXNvbnMgb24gdmFsdWUgdHlwZXMgc2hvdWxkIHdvcmsgbGlrZSB0aGV5IGRvIG9uIHBy&#xA;aW1pdGl2ZXM6PGJyPjxicj4mbmJzcDsmbmJzcDsmbmJzcDsgdmFsdWUgY2xhc3MgUG9pbnQgeyAu&#xA;Li4gfTxicj48YnI+Jm5ic3A7Jm5ic3A7Jm5ic3A7IC4uLiBjbGllbnQgY29kZSAuLi48YnI+PGJy&#xA;PiZuYnNwOyZuYnNwOyZuYnNwOyAvKiBtdXRhYmxlICovPGJyPiZuYnNwOyZuYnNwOyZuYnNwOyBQ&#xA;b2ludCBsb2NhdGlvbjs8YnI+PGJyPiZuYnNwOyZuYnNwOyZuYnNwOyB2b2lkIHNldExvY2F0aW9u&#xA;KFBvaW50IHApIHs8YnI+Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7&#xA;IGlmIChwICE9IGxvY2F0aW9uKSB7PGJyPiZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZu&#xA;YnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyBmaXJlRXhwZW5zaXZlUHJvcGVydHlD&#xA;aGFuZ2VFdmVudChsb2NhdGlvbiwgcCk7PGJyPiZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw&#xA;OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyB0aGlzLmxvY2F0aW9uID0gcDs8&#xA;YnI+Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7IH08YnI+Jm5ic3A7&#xA;Jm5ic3A7Jm5ic3A7IH08YnI+PGJyPlVzZXJzIHdpbGwgcmVhc29uYWJseSBleHBlY3QgdGhpcyBp&#xA;ZGlvbSB0byB3b3JrLCBqdXN0IGFzIHRoZXkgd291bGQgZm9yIGBpbnRgIHByb3BlcnRpZXMuJm5i&#xA;c3A7IDxicj48YnI+VGhlcmUgaGF2ZSBiZWVuIGF0IGxlYXN0IGZvdXIgc3VnZ2VzdGVkIHRyZWF0&#xA;bWVudHMgb2YgYHZhbD09YDo8YnI+PGJyPiZuYnNwOy0gSWxsZWdhbDsgY29tcGlsYXRpb24gZXJy&#xA;b3I8YnI+Jm5ic3A7LSBBbHdheXMgZmFsc2U7IHVzZXIgbXVzdCBmb2xsb3cgdXAgd2l0aCBgLmVx&#xA;dWFscygpYCB0ZXN0PGJyPiZuYnNwOy0gU3Vic3RpdHV0aWJpbGl0eSB0ZXN0IC0tIGFyZSB0aGVz&#xA;ZSB0aGUgc2FtZSB2YWx1ZTxicj4mbmJzcDstIERlbGVnYXRlIHRvIGAuZXF1YWxzKClgIChjYWxs&#xA;IHRoaXMgImRlZXAgc3Vic3RpdHV0aWJpbGl0eSIpPGJyPjxicj5JIHRoaW5rIHRoZSBmaXJzdCBp&#xA;cyB1bnJlYXNvbmFibGUgYW5kIHNob3VsZCBiZSBkaXNjYXJkZWQsIGJhc2VkIG9uIHRoZSBhYm92&#xA;ZSBpbGx1c3RyYXRpb24gb2YgZmFpbHVyZSB0byAid29yayBsaWtlIGFuIGludCI7IEkgdGhpbmsg&#xA;dGhlIHNlY29uZCBpcyB0aGUgc2FtZS4mbmJzcDsgPGJyPjxicj5XZSBleHBlY3QgZ2VuZXJpYyBj&#xA;b2RlIHRvIHVzZSB0aGUgTElGRSBpZGlvbTo8YnI+PGJyPiZuYnNwOyZuYnNwOyZuYnNwOyAoeCA9&#xA;PSB5KSB8fCB4LmVxdWFscyh5KTxicj48YnI+VGhlIExJRkUgaWRpb20gYXJvc2UgYmVjYXVzZSBg&#xA;cmVmPT1gIGlzIGZhc3QsIGFuZCBzbyB3ZSBjYW4gb3B0aW1pemUgYXdheSB0aGUgcG90ZW50aWFs&#xA;bHkgZXhwZW5zaXZlIGAuZXF1YWxzKClgIGNhbGwgd2hlbiBjYWxsZWQgd2l0aCBpZGVudGljYWwg&#xA;b2JqZWN0cy4mbmJzcDsgQnV0LCBpZiB0aGUgYHZhbD09YCB0ZXN0IGJlY29tZXMgbW9yZSBleHBl&#xA;bnNpdmUsIHRoZW4gd2hhdCBzdGFydGVkIG91dCBhcyBhbiBvcHRpbWl6YXRpb24sIG1pZ2h0IGxl&#xA;YWQgdG8gZHVwbGljYXRpb24gb2Ygbm9udHJpdmlhbCB3b3JrLCBiZWNhdXNlIHRoZSBgLmVxdWFs&#xA;cygpYCBpbXBsZW1lbnRhdGlvbiBtYXkgd2VsbCBhbHNvIGhhdmUgYW4gYD09YCB0ZXN0LiZuYnNw&#xA;OyBCdXQsIHdlIGRvbid0IHdhbnQgdG8gbGV0IHRoZSBvcHRpbWl6YXRpb24gdGFpbCB3YWcgdGhl&#xA;IGRvZyBoZXJlLiZuYnNwOyA8YnI+PGJyPlNlcGFyYXRlbHksIHdlIGhhdmUgYmVlbiByZWx1Y3Rh&#xA;bnQgdG8gcHVzaCB2YWx1ZSBzdWJzdGl0dXRpYmlsaXR5IGludG8gYGFjbXBgLCBmb3IgZmVhciBv&#xA;ZiBwZXJ0dXJiaW5nIHRoZSBwZXJmb3JtYW5jZSBtb2RlbCB0aGVyZS4mbmJzcDsgU28sIGxldCdz&#xA;IHBvc2l0IGEgYHZjbXBgLCBhIHNpYmxpbmcgdG8gYHtpbGRmfWNtcGAsIGFuZCB0cmFuc2xhdGUg&#xA;YHZhbD09YCB0byB0aGF0LCBhbmQgbGV0IGBhY21wYCBjb250aW51ZSB0byByZXR1cm4gZmFsc2Ug&#xA;d2hlbiBlaXRoZXIgb3BlcmFuZCBpcyBhIHZhbHVlLiZuYnNwOyA8YnI+PGJyPk5vdywgZm9yIHB1&#xA;cmUgdmFsdWUgY29kZSwgbGlrZSB0aGUgYWJvdmUsIHdlIHRyYW5zbGF0ZSBgdmFsPT1gIHRvIGB2&#xA;Y21wYCwgYW5kIHdlIHdvcmsgbGlrZSBhbiBpbnQuJm5ic3A7IEFuZCBmb3IgZ2VuZXJpYyBjb2Rl&#xA;LCB0aGUgTElGRSBpZGlvbTo8YnI+PGJyPiZuYnNwOyZuYnNwOyZuYnNwOyB4ID09IHkgfHwgeC5l&#xA;cXVhbHMoeSk8YnI+PGJyPih3aGVuIGB4YCBhbmQgYHlgIGFyZSBvZiB0eXBlIGBUYCkgdHJhbnNs&#xA;YXRlcyB0byBhbiBgYWNtcGAgYmFja2VkIHVwIGJ5IGFuIGBpbnZva2V2aXJ0dWFsYCwgYW5kIHdo&#xA;ZW4gYFRgIGlzIHNwZWNpYWxpemVkIHRvIGEgdmFsdWUsIHRoZSBgYWNtcGAgaXMgZmFzdCBhbmQg&#xA;YWx3YXlzIGZhbHNlLCBhbmQgd2hlbiBzcGVjaWFsaXplZCB0byBhIHJlZmVyZW5jZSwgaXMgZmFz&#xA;dCBhbmQgY29tcHV0ZXMgYHJlZj09YC4mbmJzcDsgSSBiZWxpZXZlIHRoaXMgZ2l2ZXMgZXZlcnlv&#xA;bmUgd2hhdCB0aGV5IHdhbnQ6PGJyPjxicj4mbmJzcDstIHZhbHVlIGVxdWFsaXR5IGlzIGludHVp&#xA;dGl2ZSBhbmQgYXBwcm9wcmlhdGVseSBmYXN0PGJyPiZuYnNwOy0gRXhpc3RpbmcgZ2VuZXJpY3Mg&#xA;Y29udGludWUgdXNpbmcgTElGRSwgYW5kIGdldCBmYXN0IChlbm91Z2gpIHRyYW5zbGF0aW9uIGJv&#xA;dGggZm9yIHJlZmVyZW5jZSBhbmQgdmFsdWUgaW5zdGFudGlhdGlvbnM8YnI+Jm5ic3A7LSBHZW5l&#xA;cmljIGNvZGUgdGhhdCBmb3JnZXRzIGAuZXF1YWxzKClgIGlzIGVxdWFsbHkgd3JvbmcgZm9yIHJl&#xA;ZmVyZW5jZSBhbmQgdmFsdWUgaW5zdGFudGlhdGlvbnM8YnI+Jm5ic3A7LSBHZW5lcmljIGNvZGUg&#xA;dGhhdCBnb2VzIHN0cmFpZ2h0IHRvIGAuZXF1YWxzKClgIHdvcmtzIGNvcnJlY3RseSBmb3IgcmVm&#xA;ZXJlbmNlIGFuZCB2YWx1ZSBpbnN0YW50aWF0aW9uPGJyPjxicj48YnI+PGJyPjwvdHQ+"
style="height:0;width:0;max-height:0;max-width:0;overflow:hidden;font-size:0em;padding:0;margin:0;">​</div>
    </div>
  </body>
</html>