<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    <p><br>
    </p>
    <br>
    <div class="moz-cite-prefix">On 07/07/17 17:04, Dmitry Petrashko
      wrote:<br>
    </div>
    <blockquote type="cite"
      cite="mid:356BE109-1EFD-4C93-BCED-D6BF758508B3@gmail.com">
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
      <div style="font-family:sans-serif">
        <div style="white-space:normal">
          <p dir="auto">On 7 Jul 2017, at 17:17, Maurizio Cimadamore
            wrote:</p>
        </div>
        <div style="white-space:normal">
          <blockquote style="border-left:2px solid #777; color:#777;
            margin:0 0 5px; padding-left:5px">
            <p dir="auto">I understand. In our mind, 'var' is simply a
              way to tell the compiler "type missing here, please fill
              it out" - and we'd like to keep the type inference as
              orthogonal as possible from other related semantics.</p>
          </blockquote>
        </div>
        <div style="white-space:normal">
          <p dir="auto">This is also how it behaves in scala if you
            don’t ascribe the type in pattern. The type will be filled
            in by typer. Based on <a
              href="http://cr.openjdk.java.net/%7Ebriangoetz/amber/pattern-match.html"
              style="color:#3983C4" moz-do-not-send="true">http://cr.openjdk.java.net/~briangoetz/amber/pattern-match.html</a></p>
          <pre style="background-color:#F7F7F7; border-radius:5px 5px 5px 5px; margin-left:15px; margin-right:15px; max-width:90vw; overflow-x:auto; padding:5px" bgcolor="#F7F7F7"><code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0" bgcolor="#F7F7F7">exprswitch(b) {
        case Box(var n) -> n;
    };
</code></pre>
          <p dir="auto">is equivalent to this in Scala:</p>
          <pre style="background-color:#F7F7F7; border-radius:5px 5px 5px 5px; margin-left:15px; margin-right:15px; max-width:90vw; overflow-x:auto; padding:5px" bgcolor="#F7F7F7"><code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0" bgcolor="#F7F7F7">x match {
        case Box(n) => n;
    };
</code></pre>
          <p dir="auto">Or am I misinterpreting? </p>
        </div>
      </div>
    </blockquote>
    They are the same yes. What I was trying to say, is that when
    there's no manifest type you seem to let 'null' in (because of the
    lack of instanceof under the hood), so two similarly looking
    patterns have different behavior w.r.t. nulls, which I'm not wild
    about (but I have never noticed it either having used Scala :-))<br>
    <blockquote type="cite"
      cite="mid:356BE109-1EFD-4C93-BCED-D6BF758508B3@gmail.com">
      <div style="font-family:sans-serif">
        <div style="white-space:normal">
        </div>
        <div style="white-space:normal">
          <blockquote style="border-left:2px solid #777; color:#777;
            margin:0 0 5px; padding-left:5px">
            <blockquote style="border-left:2px solid #777; color:#999;
              margin:0 0 5px; padding-left:5px; border-left-color:#999">
              <p dir="auto">In Scala, the runtime uses |instanceof| test
                (Option 1 in your writeup),<br>
                while the exhaustivity checkers uses type system and
                assumes absence of null (Option 2).<br>
                For generics, we issue a warning that type parameters
                are unchecked.<br>
                Have you considered this option?<br>
              </p>
            </blockquote>
            <p dir="auto">So, you are saying that Scala does option 1 -
              but it tones it a bit down by emitting a warning (rather
              than an harsh error) when generic types are found.<br>
              <br>
              This seems a sensible option - the only thing I don't
              understand from your description - what does Scala do for
              nested patterns? Is it another instanceof? If that's the
              case, does it means that I cannot match against a List
              whose head is null with a normal nested type test pattern?</p>
          </blockquote>
        </div>
        <div style="white-space:normal">
          <p dir="auto">Scala behaves the same way for top level and
            nested patters:</p>
        </div>
      </div>
    </blockquote>
    Yep - that's what I feared :-)<br>
    <br>
    I think that, basically, the differences we're seeing here is that
    my claim that 'case var t' is just a shorthand for 'case T t' is not
    as obvious as I thought it would have been.<br>
    <br>
    In Scala var patterns and test patterns are two different things,
    and treated in quite different ways (which means different null
    behavior).<br>
    <br>
    As I said in my earlier email, I have a feeling that keeping
    'var'-ness out of the equation might result in better
    compositionality (after all, patterns are not the only place where
    we intend to use 'var').<br>
    <br>
    Maurizio<br>
    <blockquote type="cite"
      cite="mid:356BE109-1EFD-4C93-BCED-D6BF758508B3@gmail.com">
      <div style="font-family:sans-serif">
        <div style="white-space:normal">
          <p dir="auto">Lets say that we have <code
              style="background-color:#F7F7F7; border-radius:3px;
              margin:0; padding:0 0.4em" bgcolor="#F7F7F7">case class
              Cons(hd: Object, tl: Cons)</code></p>
          <pre style="background-color:#F7F7F7; border-radius:5px 5px 5px 5px; margin-left:15px; margin-right:15px; max-width:90vw; overflow-x:auto; padding:5px" bgcolor="#F7F7F7"><code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0" bgcolor="#F7F7F7">x match {
 case Cons(a, b) => 1       // will match only if `x instanceof Cons`. will match even if a is null and b is null
 case Cons(a, b: Cons) => 2 // will not match if b is null, but a may be null
 case a: Cons => 3          // will not match null, is equivalent to the first option
 case a => 4                // always matches
}
</code></pre>
          <p dir="auto">now, details about type parameters and type
            inference:</p>
          <pre style="background-color:#F7F7F7; border-radius:5px 5px 5px 5px; margin-left:15px; margin-right:15px; max-width:90vw; overflow-x:auto; padding:5px" bgcolor="#F7F7F7"><code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0" bgcolor="#F7F7F7">case class Cons[T](hd: T, tl: Cons)

x match {
 case Cons(a, b) => 1       // a will be inferred to be Any, our top type
 case Cons[Int](a, b) => 2  // warning will be emitted that Cons[Int] is unchecked.
}

</code></pre>
          <p dir="auto">In practice, people rarely see this warning due
            to important observation that compiler uses:</p>
          <pre style="background-color:#F7F7F7; border-radius:5px 5px 5px 5px; margin-left:15px; margin-right:15px; max-width:90vw; overflow-x:auto; padding:5px" bgcolor="#F7F7F7"><code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0" bgcolor="#F7F7F7">case class Cons[T](hd: T, tl: Cons) extends Seq[T]

val x: Seq[Int] = ???

x match {
 case Cons[Int](a, b) => 2  // a warning will not be emitted, as we know that T is the same as in Seq and we “trust” x.
}

</code></pre>
          <p dir="auto">Best,<br>
            Dmitry</p>
        </div>
      </div>
    </blockquote>
    <br>
  </body>
</html>