<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    <tt>As I outlined in the mail on the survey, I think there are three
      possible ways to treat primitive type test patterns and numeric
      constant patterns (when the target type is a reference type):<br>
      <br>
      1.  Treat them as if they were synonyms for their box type.  <br>
      2.  Treat them as matching a set of values; for example, "int x"
      matches integers in the traditional 32 bit range, unboxing numeric
      targets and comparing their values.<br>
      3.  Outlaw them, to avoid confusion or to preserve the opportunity
      to do either (1) or (2) later.<br>
      <br>
      For my mind, I think #2 is the "right" answer; I think #1 would be
      a sad answer.  But, there are two additional considerations I'd
      add:<br>
       - As the survey showed, there would be a significant education
      component of choosing #2, and;<br>
       - There isn't really an overwhelming need for being able to say
      "Is this Object a numeric zero" or "Is this object a boxed
      primitive in the range of int."  <br>
      <br>
      Taken together, these lead me to #3 -- rather than choose between
      something sad and something that makes developers heads explode,
      just do neither.  I don't think this is a bad choice.  <br>
      <br>
      Concretely, what I'd propose is:<br>
      <br>
      Only allow primitive type test patterns in type-restating
      contexts.  This means that<br>
      <br>
          switch (anObject) {<br>
              case int x: ...<br>
          }<br>
      <br>
      is no good -- you'd have to say Integer x or Number x or something
      more specific.  But you could say:<br>
      <br>
          switch (anObject) {<br>
              case Point(int x, int y): ...<br>
          }<br>
      <br>
      because the types of the extracted components of Point are int,
      and therefore the type test pattern is type-restating (statically
      provable to match.)  <br>
      <br>
      Similarly, for numeric constant patterns, only allow them in
      switches where the target type is a primitive or a primitive box. 
      <br>
      <br>
      There are ample workarounds where the user can explicitly say what
      they want, if they need to -- but I don't think it will actually
      come up very often.  And this choice leaves us the option to
      pursue either #1 or #2 later, if it turns out that we underestimated
      how often people want to do this.<br>
      <br>
      This also sidesteps the question of dominance, since the confusing
      cases below (like Integer vs int) will not come up except in
      situations where we can prove they are equivalent.  <br>
      <br>
    </tt><br>
    <div class="moz-cite-prefix">On 11/3/2017 6:47 AM, Gavin Bierman
      wrote:<br>
    </div>
    <blockquote type="cite"
      cite="mid:DC28796E-3016-4117-8176-72E055B4FE7A@oracle.com">
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
      <h2 id="primitive-type-test-patterns" style="box-sizing:
        border-box; margin-bottom: 16px; line-height: 1.225;
        padding-bottom: 0.3em; color: rgb(51, 51, 51); font-family:
        'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans,
        sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI
        Symbol'; margin-top: 0px !important;" class="">Primitive
        type-test patterns</h2>
      <p style="box-sizing: border-box; margin-top: 0px; margin-bottom:
        16px; color: rgb(51, 51, 51); font-family: 'Helvetica Neue',
        Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color
        Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px;"
        class="">Given that patterns include constant expressions, and
        type tests possibly including generic types; it seems reasonable
        to consider the possibility of allowing primitive type tests in
        pattern matching. (This answers a sometimes-requested feature:
        can <code style="white-space: pre; box-sizing: border-box; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; font-size: 13.600000381469727px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">instanceof</code> support
        primitive types?)</p>
      <p style="box-sizing: border-box; margin-top: 0px; margin-bottom:
        16px; color: rgb(51, 51, 51); font-family: 'Helvetica Neue',
        Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color
        Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px;"
        class="">However, it is not wholly obvious what this test might
        mean. One possibility is that a “type-restating” equivalent for
        primitive type-test patterns is assignment conversion; e.g. if I
        have</p>
      <pre style="box-sizing: border-box; overflow: auto; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 13.600000381469727px; margin-top: 0px; margin-bottom: 16px; font-stretch: normal; line-height: 1.45; padding: 16px; background-color: rgb(247, 247, 247); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-wrap: normal; color: rgb(51, 51, 51);" class=""><code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; padding: 0px; margin: 0px; background-color: transparent; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-break: normal; border: 0px; display: inline; line-height: inherit; word-wrap: normal;" class="">case int x:</code></pre>
      <p style="box-sizing: border-box; margin-top: 0px; margin-bottom:
        16px; color: rgb(51, 51, 51); font-family: 'Helvetica Neue',
        Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color
        Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px;"
        class="">then a target whose static type is <code style="white-space: pre; box-sizing: border-box; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; font-size: 13.600000381469727px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">byte</code>, <code style="white-space: pre; box-sizing: border-box; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; font-size: 13.600000381469727px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">short</code>, <code style="white-space: pre; box-sizing: border-box; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; font-size: 13.600000381469727px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">char</code>,
        or <code style="white-space: pre; box-sizing: border-box; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; font-size: 13.600000381469727px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">int</code> –
        or their boxes – will be statically deemed to match.</p>
      <p style="box-sizing: border-box; margin-top: 0px; margin-bottom:
        16px; color: rgb(51, 51, 51); font-family: 'Helvetica Neue',
        Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color
        Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px;"
        class="">A target whose <em style="box-sizing: border-box;"
          class="">dynamic</em> type can be assigned to the primitive
        type through a combination of unboxing and widening (again,
        assignment conversion) matches a primitive type test. So if we
        have:</p>
      <pre style="box-sizing: border-box; overflow: auto; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 13.600000381469727px; margin-top: 0px; margin-bottom: 16px; font-stretch: normal; line-height: 1.45; padding: 16px; background-color: rgb(247, 247, 247); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-wrap: normal; color: rgb(51, 51, 51);" class=""><code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; padding: 0px; margin: 0px; background-color: transparent; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-break: normal; border: 0px; display: inline; line-height: inherit; word-wrap: normal;" class="">switch (o) {
    case int i: ...</code></pre>
      <p style="box-sizing: border-box; margin-top: 0px; margin-bottom:
        16px; color: rgb(51, 51, 51); font-family: 'Helvetica Neue',
        Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color
        Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px;"
        class="">we have to do <code style="white-space: pre; box-sizing: border-box; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; font-size: 13.600000381469727px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">instanceof</code> tests
        against {<code style="white-space: pre; box-sizing: border-box; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; font-size: 13.600000381469727px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">Integer</code>,<code style="white-space: pre; box-sizing: border-box; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; font-size: 13.600000381469727px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">Short</code>,<code style="white-space: pre; box-sizing: border-box; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; font-size: 13.600000381469727px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">Character</code>,<code style="white-space: pre; box-sizing: border-box; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; font-size: 13.600000381469727px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">Boolean</code>}
        to determine a match.</p>
      <p style="box-sizing: border-box; margin-top: 0px; margin-bottom:
        16px; color: rgb(51, 51, 51); font-family: 'Helvetica Neue',
        Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color
        Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px;"
        class="">A primitive type test pattern dominates other primitive
        type patterns according to assingment compatibility; <code style="white-space: pre; box-sizing: border-box; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; font-size: 13.600000381469727px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">int</code> dominates <code style="white-space: pre; box-sizing: border-box; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; font-size: 13.600000381469727px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">byte</code>/<code style="white-space: pre; box-sizing: border-box; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; font-size: 13.600000381469727px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">short</code>/<code style="white-space: pre; box-sizing: border-box; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; font-size: 13.600000381469727px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">char</code>, <code style="white-space: pre; box-sizing: border-box; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; font-size: 13.600000381469727px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">long</code> dominates <code style="white-space: pre; box-sizing: border-box; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; font-size: 13.600000381469727px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">int</code>/<code style="white-space: pre; box-sizing: border-box; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; font-size: 13.600000381469727px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">byte</code>/<code style="white-space: pre; box-sizing: border-box; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; font-size: 13.600000381469727px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">short</code>/<code style="white-space: pre; box-sizing: border-box; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; font-size: 13.600000381469727px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">char</code>,
        and <code style="white-space: pre; box-sizing: border-box; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; font-size: 13.600000381469727px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">double</code> dominates <code style="white-space: pre; box-sizing: border-box; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; font-size: 13.600000381469727px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">float</code>.</p>
      <p style="box-sizing: border-box; margin-top: 0px; margin-bottom:
        16px; color: rgb(51, 51, 51); font-family: 'Helvetica Neue',
        Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color
        Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px;"
        class="">A primitive type test pattern is inapplicable (dead) if
        cast conversion from the static type of the target fails:</p>
      <pre style="box-sizing: border-box; overflow: auto; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 13.600000381469727px; margin-top: 0px; margin-bottom: 16px; font-stretch: normal; line-height: 1.45; padding: 16px; background-color: rgb(247, 247, 247); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-wrap: normal; color: rgb(51, 51, 51);" class=""><code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; padding: 0px; margin: 0px; background-color: transparent; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-break: normal; border: 0px; display: inline; line-height: inherit; word-wrap: normal;" class="">Map m;
switch (m) {
    case int x:  // compile error
}</code></pre>
      <p style="box-sizing: border-box; margin-top: 0px; margin-bottom:
        16px; color: rgb(51, 51, 51); font-family: 'Helvetica Neue',
        Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color
        Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px;"
        class="">The dominance interaction between primitive type-tests
        and reference type-tests for the wrapper types (and their
        supertypes) seems messy. Consider the following combinations:</p>
      <pre style="box-sizing: border-box; overflow: auto; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 13.600000381469727px; margin-top: 0px; margin-bottom: 16px; font-stretch: normal; line-height: 1.45; padding: 16px; background-color: rgb(247, 247, 247); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-wrap: normal; color: rgb(51, 51, 51);" class=""><code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; padding: 0px; margin: 0px; background-color: transparent; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-break: normal; border: 0px; display: inline; line-height: inherit; word-wrap: normal;" class="">case int n:
case Integer n:  // dead

case Integer n:
case int n:      // not dead -- still matches Short, Byte

case Byte b:
case byte b:     // dead

case Number n:
case int n:      // dead</code></pre>
      <div style="box-sizing: border-box; margin-top: 0px; color:
        rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica,
        'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji',
        'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px;
        margin-bottom: 0px !important;" class="">Is there some unifying
        theory that makes sense here? One possibility is to take a more
        denotational view: a type is a set of values, so type
        restatement is really about semantic set inclusion, and dynamic
        testing is about set membership. Is this adding too much
        complexity? Do developers really care about this feature?</div>
    </blockquote>
    <br>
  </body>
</html>