2

While reviewing a code change I found Array.empty not Array() that I would consider more idiomatic. I was then surprised to have learnt that == them gives false yet they appear equal type- and value-wise.

scala> Array.empty == Array()
res1: Boolean = false

scala> Array.empty
res2: Array[Nothing] = Array()

scala> Array()
res3: Array[Nothing] = Array()

Could anyone explain why is so?

chrylis -cautiouslyoptimistic-
  • 75,269
  • 21
  • 115
  • 152
Jacek Laskowski
  • 72,696
  • 27
  • 242
  • 420
  • 1
    How does `==` work in Scala? Reference identity like in Java? Or more like `equals`? – Thilo May 26 '14 at 23:39
  • @Thilo, it depends on the type – RomanI May 26 '14 at 23:40
  • 2
    I believe it is answered here: http://stackoverflow.com/a/3738850/384442 – RomanI May 26 '14 at 23:41
  • The debate between `Array.empty` and `Array()` might not be a dupe. If they don't close it as argumentative and opinioned, I'd vote for `empty` as more explicit and one less opcode (because no empty vararg). – som-snytt May 27 '14 at 00:37

1 Answers1

5

That's actually more of a Java question. Because in Java, which Scala's Array is exactly using, array equality is identity equality.

// scala                   compiles as such Java           is equal to
Array.empty == Array() === Array.empty.equals(Array()) === false

The proper way to check Array equality based on structure is:

java.util.Arrays.equals(Array.empty, Array()) === true

Arrays are a very special beast on the JVM - intuition often fails with them. Scala had to carry over this definition in order to keep compatibility with Java stuffs.

Konrad 'ktoso' Malawski
  • 13,102
  • 3
  • 47
  • 52
  • Or `Arrays.deepEquals`. Sad situation. – Thilo May 26 '14 at 23:44
  • Interesting. How could I know in Scala REPL that Array is based on Java's? – Jacek Laskowski May 26 '14 at 23:58
  • not "in the REPL" but everywhere. Well - books or scaladocs - there's a lot of links in there http://www.scala-lang.org/api/2.10.3/index.html#scala.Array – Konrad 'ktoso' Malawski May 27 '14 at 00:17
  • 2
    Actually the test compiles to `BoxesRunTime.equals`. Special equality could have been implemented there. You can witness that Scala arrays are Java arrays by entering `Array(1)` and then `:javap -` to see `newarray` in the constructor of the result. – som-snytt May 27 '14 at 00:27
  • In Scala, you can use `sameElements` for comparing `Seq`s, and there are implicit conversion that make this work for `Array` as well: `Array(1) sameElements Array(1)`. Unfortunately `Array.empty sameElements Array()` doesn't work because of issues with type parameters. – wingedsubmariner May 27 '14 at 05:15