Quantcast

[scala] Array equality

classic Classic list List threaded Threaded
43 messages Options
123
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[scala] Array equality

fft1976
Am I missing something totally obvious, or are arrays never equal?

===============================

Welcome to Scala version 2.7.3.final (OpenJDK Client VM, Java 1.6.0_0).
Type in expressions to have them evaluated.
Type :help for more information.

scala> Array(1) == Array(1)
res0: Boolean = false

scala> Array(1) eq Array(1)
res1: Boolean = false

scala> Array(1) === Array(1)
<console>:5: error: value === is not a member of Array[Int]
       Array(1) === Array(1)
                ^

scala> Array(1) equals Array(1)
res3: Boolean = false
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [scala] Array equality

Tony Morris
FFT wrote:

> Am I missing something totally obvious, or are arrays never equal?
>
> ===============================
>
> Welcome to Scala version 2.7.3.final (OpenJDK Client VM, Java 1.6.0_0).
> Type in expressions to have them evaluated.
> Type :help for more information.
>
> scala> Array(1) == Array(1)
> res0: Boolean = false
>
> scala> Array(1) eq Array(1)
> res1: Boolean = false
>
> scala> Array(1) === Array(1)
> <console>:5: error: value === is not a member of Array[Int]
>        Array(1) === Array(1)
>                 ^
>
> scala> Array(1) equals Array(1)
> res3: Boolean = false
>
>  
== uses Java's Object.equals method. In Java, this also consistently
produces false, since the implementation compares reference values for
array types.

Alternatively, you can use the sameElements method or if you have Scalaz
and want more flexibility, there is a === method which uses implicits to
look up the strategy to test for equality.

--
Tony Morris
http://tmorris.net/


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[scala] Re: Array equality

fft1976
In reply to this post by fft1976
By the way, I understand that some of the equalities are reference
equalities and others are supposedly structural equalities, but here
all of ==, eq and equals return "false", whereas for Lists == and
equals return "true". Is this an oversight?

On Mon, Apr 20, 2009 at 9:41 PM, FFT <[hidden email]> wrote:

> Am I missing something totally obvious, or are arrays never equal?
>
> ===============================
>
> Welcome to Scala version 2.7.3.final (OpenJDK Client VM, Java 1.6.0_0).
> Type in expressions to have them evaluated.
> Type :help for more information.
>
> scala> Array(1) == Array(1)
> res0: Boolean = false
>
> scala> Array(1) eq Array(1)
> res1: Boolean = false
>
> scala> Array(1) === Array(1)
> <console>:5: error: value === is not a member of Array[Int]
>       Array(1) === Array(1)
>                ^
>
> scala> Array(1) equals Array(1)
> res3: Boolean = false
>
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [scala] Re: Array equality

Tony Morris
FFT wrote:

> By the way, I understand that some of the equalities are reference
> equalities and others are supposedly structural equalities, but here
> all of ==, eq and equals return "false", whereas for Lists == and
> equals return "true". Is this an oversight?
>
> On Mon, Apr 20, 2009 at 9:41 PM, FFT <[hidden email]> wrote:
>  
>> Am I missing something totally obvious, or are arrays never equal?
>>
>> ===============================
>>
>> Welcome to Scala version 2.7.3.final (OpenJDK Client VM, Java 1.6.0_0).
>> Type in expressions to have them evaluated.
>> Type :help for more information.
>>
>> scala> Array(1) == Array(1)
>> res0: Boolean = false
>>
>> scala> Array(1) eq Array(1)
>> res1: Boolean = false
>>
>> scala> Array(1) === Array(1)
>> <console>:5: error: value === is not a member of Array[Int]
>>       Array(1) === Array(1)
>>                ^
>>
>> scala> Array(1) equals Array(1)
>> res3: Boolean = false
>>
>>    
>
>  
No it is not an oversight -- any more than it is for Java anyway.

class T {
  public static void main(String[] args) {
    final String[] x = new String[] { "a", "b", "c" };
    final String[] y = new String[] { "a", "b", "c" };
    System.out.println(x == y); // false
    System.out.println(x.equals(y)); // false
  }
}

To use === you'll need Scalaz which is third-party.

--
Tony Morris
http://tmorris.net/


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [scala] Re: Array equality

fft1976
On Mon, Apr 20, 2009 at 11:33 PM, Tony Morris <[hidden email]> wrote:

> No it is not an oversight -- any more than it is for Java anyway.

java.util.ArrayList though works as I would expect, as does
java.util.Arrays.equals.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [scala] Re: Array equality

Tony Morris
FFT wrote:

> On Mon, Apr 20, 2009 at 11:33 PM, Tony Morris <[hidden email]> wrote:
>
>  
>> No it is not an oversight -- any more than it is for Java anyway.
>>    
>
> java.util.ArrayList though works as I would expect, as does
> java.util.Arrays.equals.
>
>  
If you used java.util.ArrayList (equals) or java.util.Array.equals from
Scala, you'd get the same result you get in Java -- just the same as you
did when using ==.

When you're using == you're calling Java's Object.equals method, which
behaves exactly as it would in Java. If any oversight exists, it does so
in the API of Java.

--
Tony Morris
http://tmorris.net/


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [scala] Re: Array equality

Vlad Patryshev
In reply to this post by Tony Morris
== is the same as equals, is not it? eq is referential equality.

Arrays in Java, traditionally, don't have a reasonable equals method.

2009/4/20 Tony Morris <[hidden email]>
FFT wrote:
> By the way, I understand that some of the equalities are reference
> equalities and others are supposedly structural equalities, but here
> all of ==, eq and equals return "false", whereas for Lists == and
> equals return "true". Is this an oversight?
>
> On Mon, Apr 20, 2009 at 9:41 PM, FFT <[hidden email]> wrote:
>
>> Am I missing something totally obvious, or are arrays never equal?
>>
>> ===============================
>>
>> Welcome to Scala version 2.7.3.final (OpenJDK Client VM, Java 1.6.0_0).
>> Type in expressions to have them evaluated.
>> Type :help for more information.
>>
>> scala> Array(1) == Array(1)
>> res0: Boolean = false
>>
>> scala> Array(1) eq Array(1)
>> res1: Boolean = false
>>
>> scala> Array(1) === Array(1)
>> <console>:5: error: value === is not a member of Array[Int]
>>       Array(1) === Array(1)
>>                ^
>>
>> scala> Array(1) equals Array(1)
>> res3: Boolean = false
>>
>>
>
>
No it is not an oversight -- any more than it is for Java anyway.

class T {
 public static void main(String[] args) {
   final String[] x = new String[] { "a", "b", "c" };
   final String[] y = new String[] { "a", "b", "c" };
   System.out.println(x == y); // false
   System.out.println(x.equals(y)); // false
 }
}

To use === you'll need Scalaz which is third-party.

--
Tony Morris
http://tmorris.net/





--
Thanks,
-Vlad
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[scala] Re: Array equality

Jesper Nordenberg
Vlad Patryshev wrote:
> == is the same as equals, is not it? eq is referential equality.
>
> Arrays in Java, traditionally, don't have a reasonable equals method.

Since arrays are mutable I think it's a very reasonable equals method.

/Jesper Nordenberg

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [scala] Re: Array equality

fft1976
On Tue, Apr 21, 2009 at 12:28 AM, Jesper Nordenberg <[hidden email]> wrote:
> Vlad Patryshev wrote:
>>
>> == is the same as equals, is not it? eq is referential equality.

In Java:

new Integer(1) == new Integer(1); // false
(new Integer(1)).equals(new Integer(1)); // true

>> Arrays in Java, traditionally, don't have a reasonable equals method.
>
> Since arrays are mutable I think it's a very reasonable equals method.

Doesn't seem consistent with, say, Integer or ArrayList classes.

I think it would be reasonable to reserve at least one of the many
equalities to mean the equality of contents, but I may be bringing my
prejudices with me.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [scala] Re: Array equality

Tony Morris
FFT wrote:

> On Tue, Apr 21, 2009 at 12:28 AM, Jesper Nordenberg <[hidden email]> wrote:
>  
>> Vlad Patryshev wrote:
>>    
>>> == is the same as equals, is not it? eq is referential equality.
>>>      
>
> In Java:
>
> new Integer(1) == new Integer(1); // false
> (new Integer(1)).equals(new Integer(1)); // true
>  
When you use == in Scala, you're calling Object.equals (as Vlad said).

--
Tony Morris
http://tmorris.net/

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [scala] Array equality

Ricky Clarkson
In reply to this post by fft1976
Hi FFT,

There are numerous definitions of equality.  For many purposes it is a good idea for x == y to be constant for the life of x and the life of y.  Array(1) == Array(1) breaks this, as arrays can be mutated.  List(1) == List(1) doesn't, as Lists cannot be mutated.

Equality is an interesting topic, merely because of the incredible range of interpretations there are of it.

Cheers,
Ricky.

2009/4/21 FFT <[hidden email]>
Am I missing something totally obvious, or are arrays never equal?

===============================

Welcome to Scala version 2.7.3.final (OpenJDK Client VM, Java 1.6.0_0).
Type in expressions to have them evaluated.
Type :help for more information.

scala> Array(1) == Array(1)
res0: Boolean = false

scala> Array(1) eq Array(1)
res1: Boolean = false

scala> Array(1) === Array(1)
<console>:5: error: value === is not a member of Array[Int]
      Array(1) === Array(1)
               ^

scala> Array(1) equals Array(1)
res3: Boolean = false

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[scala] Re: Array equality

Jesper Nordenberg
In reply to this post by fft1976
FFT wrote:
> Doesn't seem consistent with, say, Integer or ArrayList classes.

Integer is an immutable class so that's fine. As for ArrayList I think
it's a mistake, probably stemming from the fact that there are no
immutable collection classes in the Java libraries (you can create a
dynamically checked read-only ArrayList).

> I think it would be reasonable to reserve at least one of the many
> equalities to mean the equality of contents, but I may be bringing my
> prejudices with me.

Equals should mean equality of content for immutable value types. But
for references to mutable objects my opinion is that they should never
be equal unless they reference the same object, otherwise it's
impossible to for example implement a useful hashCode() method. Sure you
can add another method that performs time variant content equality checks.

/Jesper Nordenberg

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [scala] Re: Array equality

fft1976
On Tue, Apr 21, 2009 at 1:30 AM, Jesper Nordenberg <[hidden email]> wrote:

> Equals should mean equality of content for immutable value types. But for
> references to mutable objects my opinion is that they should never be equal
> unless they reference the same object, otherwise it's impossible to for
> example implement a useful hashCode() method.

Why isn't hashCode() similarly crippled or disabled for mutable data
structures? Wouldn't that make just as much sense?

> Sure you can add another method that performs time variant content equality checks.

Can I do that without boilerplate in every class definition?
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [scala] Re: Array equality

√iktor Klang
Why isn't hashCode defined in a Hashable interface?

Why isn't it possible to define code-contracts for abstract methods/interface methods?

:(

On Tue, Apr 21, 2009 at 11:50 AM, FFT <[hidden email]> wrote:
On Tue, Apr 21, 2009 at 1:30 AM, Jesper Nordenberg <[hidden email]> wrote:

> Equals should mean equality of content for immutable value types. But for
> references to mutable objects my opinion is that they should never be equal
> unless they reference the same object, otherwise it's impossible to for
> example implement a useful hashCode() method.

Why isn't hashCode() similarly crippled or disabled for mutable data
structures? Wouldn't that make just as much sense?

> Sure you can add another method that performs time variant content equality checks.

Can I do that without boilerplate in every class definition?



--
Viktor Klang
Senior Systems Analyst
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [scala] Re: Array equality

Tony Morris
Viktor Klang wrote:
> Why isn't hashCode defined in a Hashable interface?

http://functionaljava.googlecode.com/svn/artifacts/latest/javadoc/fj/pre/Hash.html

--
Tony Morris
http://tmorris.net/


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [scala] Re: Array equality

√iktor Klang
Is this yet another case of great minds thinking alike? ;)

On Tue, Apr 21, 2009 at 12:50 PM, Tony Morris <[hidden email]> wrote:
Viktor Klang wrote:
> Why isn't hashCode defined in a Hashable interface?

http://functionaljava.googlecode.com/svn/artifacts/latest/javadoc/fj/pre/Hash.html

--
Tony Morris
http://tmorris.net/





--
Viktor Klang
Senior Systems Analyst
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[scala] Re: Array equality

Jesper Nordenberg
In reply to this post by fft1976
FFT wrote:
 > Why isn't hashCode() similarly crippled or disabled for mutable data
 > structures? Wouldn't that make just as much sense?

I didn't mean to imply that equals() is crippled for mutable objects,
it's perfectly useful. Similarly the default implementation of
Object.hashCode() is perfectly useful for mutable objects, it always
returns the same hash for an object but still provide a good
distribution over the integers.

 >> Sure you can add another method that performs time variant content
equality checks.
 >
 > Can I do that without boilerplate in every class definition?

Yes, you can "hack" case classes to make this work:

scala> trait MutableProduct extends Product { override def equals(v :
Any) = super.equals(v); override def hashCode = super.hashCode }
defined trait MutableProduct

scala> case class P(var i : Int) extends MutableProduct
defined class P

scala> P(1) == P(1)
res33: Boolean = false

Every case class in Scala implements Product, so you can write a generic
deep comparison function which will work with all case classes as well:

scala> def equalElements(v1 : Any, v2 : Any) : Boolean = (v1, v2) match {
   case (m1 : MutableProduct, m2 : MutableProduct) =>
     m1.getClass == m2.getClass &&
     (0 until m1.productArity).forall(i =>
equalElements(m1.productElement(i), m2.productElement(i)))
   case _ => v1 == v2
}
equalElements: (Any,Any)Boolean

scala> equalElements(P(1), P(1))
res42: Boolean = true

(Note that the code might be buggy)

/Jesper Nordenberg

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [scala] Re: Array equality

fft1976
On Tue, Apr 21, 2009 at 7:08 AM, Jesper Nordenberg <[hidden email]> wrote:
> Yes, you can "hack" case classes to make this work:
>

Nice...

> Every case class in Scala implements Product, so you can write a generic
> deep comparison function which will work with all case classes as well:

Why doesn't Programming In Scala talk about this? At least Product
isn't mentioned in the index.

>    m1.getClass == m2.getClass &&

Is this much slower than boilerplaty manual version would be (reflection)?
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[scala] Re: Array equality

Jesper Nordenberg
FFT wrote:
>> Every case class in Scala implements Product, so you can write a generic
>> deep comparison function which will work with all case classes as well:
>
> Why doesn't Programming In Scala talk about this? At least Product
> isn't mentioned in the index.

I have no idea. Product is a useful trait for dynamically decomposing a
case class.

>>    m1.getClass == m2.getClass &&
>
> Is this much slower than boilerplaty manual version would be (reflection)?

I except the Object.getClass() method to be very fast, it's typically
used when overriding equals().

/Jesper Nordenberg

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [scala] Re: Array equality

Ricky Clarkson
"I except the Object.getClass() method to be very fast, it's typically used when overriding equals()."

How do you use getClass in an equals implementation without violating the equals contract?

2009/4/22 Jesper Nordenberg <[hidden email]>
FFT wrote:
Every case class in Scala implements Product, so you can write a generic
deep comparison function which will work with all case classes as well:

Why doesn't Programming In Scala talk about this? At least Product
isn't mentioned in the index.

I have no idea. Product is a useful trait for dynamically decomposing a case class.


  m1.getClass == m2.getClass &&

Is this much slower than boilerplaty manual version would be (reflection)?

I except the Object.getClass() method to be very fast, it's typically used when overriding equals().

/Jesper Nordenberg


123
Loading...