43
object Main {

  def main(args: Array[String])
  {
    val x = 10
    print(x="Hello World")
    print(x)
  }
}

output : Hello World10

As we know, in Scala a val cannot be reassigned or changed, but here x is changing to

Hello World

while printing.

Bernhard Barker
  • 54,589
  • 14
  • 104
  • 138
Deepak Pandey
  • 618
  • 7
  • 19
  • 4
    it is not reassigning the value. It is just printing "Hello World" from first statement and 10 from second statement. Use println() and you'll see output in new line. – vindev Mar 13 '18 at 07:27

1 Answers1

71

Explanation is kind of unexpected: print has a parameter named x. Using x = ... uses the named argument, therefore print(x="Hello World") is the same as print("Hello World").

See Scala Predef docs or Predef.scala source:

object Predef /*....*/ {

/*....*/
  def print(x: Any) = Console.print(x)

/*....*/
}

Note: this was already discussed in Scala Internal mailing list:

Scala currently tries to be smart about treating "x = e" as a named argument or an assignment ... This can be surprising to the user ....

Proposal: we deprecate assignments in argument lists

There also exists an issue SI-8206 for this, the change was probably implemented in issue 426 for Scala 2.13.

Your code will still compile after deprecation, with the same meaning. The change will be no one (at least no one sufficiently familiar with the language specs / implementation) should expect it to be interpreted as assignment any more.

Suma
  • 33,181
  • 16
  • 123
  • 191
  • 4
    So it means this is working specifically only with variable `x`, doesn't it? – Berci Mar 13 '18 at 08:28
  • yes, its amazing it works only for x!. thats strange. – Deepak Pandey Mar 13 '18 at 08:39
  • 3
    Another thing to note is that, if you had, e.g. `var m = 12; print(m = 13); print(m);`, you'd get "()13". As for why, there is an official explanation and some other nice insights here: https://stackoverflow.com/q/1998724/5236247 – Adowrath Mar 13 '18 at 09:00