Scala Programming Language
  1. Scala Programming Language
  2. SI-5158

post-match mutation must not affect pattern variable

    Details

      Description

      case class B(var x: Int) {
        def succ() {
          x = x + 1
        }
      }
      
      object TestFoo {
        def main(args: Array[String]) {
          val b = B(0)
          b match {
            case B(x) =>
              //println(x)
              b.succ()
              println(x)
          }
        }
      }
      

      This code prints "1" instead of "0". However if you uncomment first println you will get what expected "0\n0".

        Issue Links

          Activity

          Hide
          Jason Zaugg added a comment -

          @adriaanm rather than tinkering around this to extract the non-val case class parameters eagerly, I think we should just revert to using B.unapply.

          Show
          Jason Zaugg added a comment - @adriaanm rather than tinkering around this to extract the non-val case class parameters eagerly, I think we should just revert to using B.unapply .
          Hide
          Adriaan Moors added a comment -

          unfortunately that's expensive, or do you propose we only do it for case classes with mutable variables?

          Show
          Adriaan Moors added a comment - unfortunately that's expensive, or do you propose we only do it for case classes with mutable variables?
          Hide
          Jason Zaugg added a comment -

          Yep, definitely keep the optimized version for case classes without vars. You could also do the same if it has a var parameters, but that isn't bound in the pattern.

          Show
          Jason Zaugg added a comment - Yep, definitely keep the optimized version for case classes without vars. You could also do the same if it has a var parameters, but that isn't bound in the pattern.
          Hide
          Iulian Dragos added a comment -

          I don't see what's being optimized. The number of local variables? I really doubt that has any benefit at runtime, and code size is definitely increased when there's more than one reference to a pattern variable. But all these considerations are offset by making debugging way more difficult that it was before.

          Show
          Iulian Dragos added a comment - I don't see what's being optimized. The number of local variables? I really doubt that has any benefit at runtime, and code size is definitely increased when there's more than one reference to a pattern variable. But all these considerations are offset by making debugging way more difficult that it was before.
          Hide
          Adriaan Moors added a comment -

          agreed – this is what I'm implementing now (one local var per pattern var)

          Show
          Adriaan Moors added a comment - agreed – this is what I'm implementing now (one local var per pattern var)
          Hide
          Jason Zaugg added a comment -

          By optimized, I just meant avoiding the call to unapply for a case class.

          +1 for local variables.

          Adriaan: do you plan to add locals for bound names that are used in the body, or for all bound names? The latter would be convenient while debugging.

          Show
          Jason Zaugg added a comment - By optimized, I just meant avoiding the call to unapply for a case class. +1 for local variables. Adriaan: do you plan to add locals for bound names that are used in the body, or for all bound names? The latter would be convenient while debugging.
          Hide
          Adriaan Moors added a comment -

          I'd just add all of them and let the optimizer do the rest.

          Show
          Adriaan Moors added a comment - I'd just add all of them and let the optimizer do the rest.
          Hide
          Jason Zaugg added a comment -

          One more convenience for us dirty debuggers:

          scrut match {
            case (Foo(x, y), _) =>
              // generate a var for constructor patterns
              val foo$1: Foo
          
              // in addition to the user provided binders
              val x: Int
              val y: String
          }
          
          Show
          Jason Zaugg added a comment - One more convenience for us dirty debuggers: scrut match { case (Foo(x, y), _) => // generate a var for constructor patterns val foo$1: Foo // in addition to the user provided binders val x: Int val y: String }
          Hide
          Adriaan Moors added a comment - - edited
          Show
          Adriaan Moors added a comment - - edited https://github.com/scala/scala/pull/937

            People

            • Assignee:
              Adriaan Moors
              Reporter:
              Alexander
            • Votes:
              0 Vote for this issue
              Watchers:
              5 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Development