- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
Why doesn't the compiler find this mistake...?
Wed, 2009-05-06, 22:50
Hi,
let's say i have a method
class SplayTree[ T ]()( implicit view : (T) => Ordered[ T ])
extends scala.collection.mutable.Set[ T ] {
...
def findMax: Option[ T ] = {
if( root == null ) return None
var x = root
while( x.right != null ) x = x.right
splay( x.elem )
Some( x.elem )
}
...
}
and i am testing:
val min = t.findMin
if( min != 2 ) {
println( "findMin error! Should be 2 but is " + min )
}
why doesn't the compiler tell me that i'm having a type mismatch ( if
( min != 2 ) compares an Option[ Int ] with an Int )? instead the
test fails with printout:
"findMin error! Should be 2 but is Some(2)"
... how can i avoid this problem?
thanks, -sciss-
Thu, 2009-05-07, 01:27
#2
Re: Why doesn't the compiler find this mistake...?
You might be interested in scalaz's Equal functionality: http://code.google.com/p/scalaz/source/browse/trunk/src/main/scala/scalaz/Equal.scala
This defines an Equal trait that restricts the comparison to objects of the same type. Via implicits you can then compare objects using the "===" operator and will get the compiler errors you are after.
On 07/05/2009, at 9:55 AM, Jorge Ortiz wrote:
This defines an Equal trait that restricts the comparison to objects of the same type. Via implicits you can then compare objects using the "===" operator and will get the compiler errors you are after.
On 07/05/2009, at 9:55 AM, Jorge Ortiz wrote:
Because Scala inherits == (and !=) from Java's "equals" method, which takes an Any as its argument.
How do you prevent this mistake? Try findbugs http://findbugs.sourceforge.net/
--j
On Wed, May 6, 2009 at 2:50 PM, Sciss <contact@sciss.de> wrote:Hi,
let's say i have a method
class SplayTree[ T ]()( implicit view : (T) => Ordered[ T ])
extends scala.collection.mutable.Set[ T ] {
...
def findMax: Option[ T ] = {
if( root == null ) return None
var x = root
while( x.right != null ) x = x.right
splay( x.elem )
Some( x.elem )
}
...
}
and i am testing:
val min = t.findMin
if( min != 2 ) {
println( "findMin error! Should be 2 but is " + min )
}
why doesn't the compiler tell me that i'm having a type mismatch ( if( min != 2 ) compares an Option[ Int ] with an Int )? instead the test fails with printout:
"findMin error! Should be 2 but is Some(2)"
... how can i avoid this problem?
thanks, -sciss-
Thu, 2009-05-07, 09:27
#3
Re: Why doesn't the compiler find this mistake...?
ah very nice, thank you!
Am 07.05.2009 um 02:22 schrieb Andrew O'Malley:
> You might be interested in scalaz's Equal functionality: http://
> code.google.com/p/scalaz/source/browse/trunk/src/main/scala/scalaz/
> Equal.scala
>
> This defines an Equal trait that restricts the comparison to
> objects of the same type. Via implicits you can then compare
> objects using the "===" operator and will get the compiler errors
> you are after.
>
> On 07/05/2009, at 9:55 AM, Jorge Ortiz wrote:
>
>> Because Scala inherits == (and !=) from Java's "equals" method,
>> which takes an Any as its argument.
>>
>> How do you prevent this mistake? Try findbugs http://
>> findbugs.sourceforge.net/
>>
>> --j
>>
>> On Wed, May 6, 2009 at 2:50 PM, Sciss wrote:
>> Hi,
>>
>> let's say i have a method
>>
>> class SplayTree[ T ]()( implicit view : (T) => Ordered[ T ])
>> extends scala.collection.mutable.Set[ T ] {
>>
>> ...
>>
>> def findMax: Option[ T ] = {
>> if( root == null ) return None
>> var x = root
>> while( x.right != null ) x = x.right
>> splay( x.elem )
>> Some( x.elem )
>> }
>>
>> ...
>> }
>>
>> and i am testing:
>>
>> val min = t.findMin
>> if( min != 2 ) {
>> println( "findMin error! Should be 2 but is " + min )
>> }
>>
>> why doesn't the compiler tell me that i'm having a type mismatch
>> ( if( min != 2 ) compares an Option[ Int ] with an Int )? instead
>> the test fails with printout:
>>
>> "findMin error! Should be 2 but is Some(2)"
>>
>> ... how can i avoid this problem?
>>
>> thanks, -sciss-
>>
>>
>>
>
Thu, 2009-05-07, 09:37
#4
Re: Why doesn't the compiler find this mistake...?
thank you for the findbugs link!
Am 07.05.2009 um 01:55 schrieb Jorge Ortiz:
> Because Scala inherits == (and !=) from Java's "equals" method,
> which takes an Any as its argument.
>
> How do you prevent this mistake? Try findbugs http://
> findbugs.sourceforge.net/
>
> --j
>
> On Wed, May 6, 2009 at 2:50 PM, Sciss wrote:
> Hi,
>
> let's say i have a method
>
> class SplayTree[ T ]()( implicit view : (T) => Ordered[ T ])
> extends scala.collection.mutable.Set[ T ] {
>
> ...
>
> def findMax: Option[ T ] = {
> if( root == null ) return None
> var x = root
> while( x.right != null ) x = x.right
> splay( x.elem )
> Some( x.elem )
> }
>
> ...
> }
>
> and i am testing:
>
> val min = t.findMin
> if( min != 2 ) {
> println( "findMin error! Should be 2 but is " + min )
> }
>
> why doesn't the compiler tell me that i'm having a type mismatch
> ( if( min != 2 ) compares an Option[ Int ] with an Int )? instead
> the test fails with printout:
>
> "findMin error! Should be 2 but is Some(2)"
>
> ... how can i avoid this problem?
>
> thanks, -sciss-
>
>
>
Tue, 2009-06-09, 11:37
#5
Re: Why doesn't the compiler find this mistake...?
stumpled again over the same problem.
but this
def ident[T]( a: T, b: T ) : Boolean = {
println( "Comparing a = " + a + "; with b = " + b )
a.equals( b )
}
does not inforce a and b be of the same type... i don't understand why?
like i have
val a: TypeA
val b: TypeB = TypeB.wrap( a )
implicit def bToA( x: TypeB ) : TypeA = { ... unwrap TypeA which is
stored in TypeB ... }
ident( a, b )
// --> false !!
although bToA( b ) results in a.
i'm confused....
ciao, -sciss-
Am 07.05.2009 um 02:22 schrieb Andrew O'Malley:
> You might be interested in scalaz's Equal functionality: http://
> code.google.com/p/scalaz/source/browse/trunk/src/main/scala/scalaz/
> Equal.scala
>
> This defines an Equal trait that restricts the comparison to
> objects of the same type. Via implicits you can then compare
> objects using the "===" operator and will get the compiler errors
> you are after.
>
> On 07/05/2009, at 9:55 AM, Jorge Ortiz wrote:
>
>> Because Scala inherits == (and !=) from Java's "equals" method,
>> which takes an Any as its argument.
>>
>> How do you prevent this mistake? Try findbugs http://
>> findbugs.sourceforge.net/
>>
>> --j
>>
>> On Wed, May 6, 2009 at 2:50 PM, Sciss wrote:
>> Hi,
>>
>> let's say i have a method
>>
>> class SplayTree[ T ]()( implicit view : (T) => Ordered[ T ])
>> extends scala.collection.mutable.Set[ T ] {
>>
>> ...
>>
>> def findMax: Option[ T ] = {
>> if( root == null ) return None
>> var x = root
>> while( x.right != null ) x = x.right
>> splay( x.elem )
>> Some( x.elem )
>> }
>>
>> ...
>> }
>>
>> and i am testing:
>>
>> val min = t.findMin
>> if( min != 2 ) {
>> println( "findMin error! Should be 2 but is " + min )
>> }
>>
>> why doesn't the compiler tell me that i'm having a type mismatch
>> ( if( min != 2 ) compares an Option[ Int ] with an Int )? instead
>> the test fails with printout:
>>
>> "findMin error! Should be 2 but is Some(2)"
>>
>> ... how can i avoid this problem?
>>
>> thanks, -sciss-
>>
>>
>>
>
Tue, 2009-06-09, 11:47
#6
Re: Why doesn't the compiler find this mistake...?
The issue is that Scala supports this broken feature from OOP called
'subtyping'. There is a type T that both a and b extend, even if it's
as unspecific as Any.
OOP, helping people be vague since, um..
def ident[T](a: T)(b: T): Boolean ... should do it, because Scala's
type parameter inference only looks at the first parameter list.
2009/6/9 Sciss :
> stumpled again over the same problem.
>
> but this
>
> def ident[T]( a: T, b: T ) : Boolean = {
> println( "Comparing a = " + a + "; with b = " + b )
> a.equals( b )
> }
>
> does not inforce a and b be of the same type... i don't understand why?
>
> like i have
>
> val a: TypeA
> val b: TypeB = TypeB.wrap( a )
> implicit def bToA( x: TypeB ) : TypeA = { ... unwrap TypeA which is
> stored in TypeB ... }
>
> ident( a, b )
> // --> false !!
>
> although bToA( b ) results in a.
>
> i'm confused....
>
> ciao, -sciss-
>
>
>
> Am 07.05.2009 um 02:22 schrieb Andrew O'Malley:
>
>> You might be interested in scalaz's Equal functionality:
>> http://code.google.com/p/scalaz/source/browse/trunk/src/main/scala/scala...
>>
>> This defines an Equal trait that restricts the comparison to objects of
>> the same type. Via implicits you can then compare objects using the "==="
>> operator and will get the compiler errors you are after.
>>
>> On 07/05/2009, at 9:55 AM, Jorge Ortiz wrote:
>>
>>> Because Scala inherits == (and !=) from Java's "equals" method, which
>>> takes an Any as its argument.
>>>
>>> How do you prevent this mistake? Try findbugs
>>> http://findbugs.sourceforge.net/
>>>
>>> --j
>>>
>>> On Wed, May 6, 2009 at 2:50 PM, Sciss wrote:
>>> Hi,
>>>
>>> let's say i have a method
>>>
>>> class SplayTree[ T ]()( implicit view : (T) => Ordered[ T ])
>>> extends scala.collection.mutable.Set[ T ] {
>>>
>>> ...
>>>
>>> def findMax: Option[ T ] = {
>>> if( root == null ) return None
>>> var x = root
>>> while( x.right != null ) x = x.right
>>> splay( x.elem )
>>> Some( x.elem )
>>> }
>>>
>>> ...
>>> }
>>>
>>> and i am testing:
>>>
>>> val min = t.findMin
>>> if( min != 2 ) {
>>> println( "findMin error! Should be 2 but is " + min )
>>> }
>>>
>>> why doesn't the compiler tell me that i'm having a type mismatch ( if(
>>> min != 2 ) compares an Option[ Int ] with an Int )? instead the test fails
>>> with printout:
>>>
>>> "findMin error! Should be 2 but is Some(2)"
>>>
>>> ... how can i avoid this problem?
>>>
>>> thanks, -sciss-
>>>
>>>
>>>
>>
>
>
Tue, 2009-06-09, 14:07
#7
Re: Why doesn't the compiler find this mistake...?
ah ok, thanks for the explanation + the trick to do it!
ciao, -sciss-
Am 09.06.2009 um 12:41 schrieb Ricky Clarkson:
> The issue is that Scala supports this broken feature from OOP called
> 'subtyping'. There is a type T that both a and b extend, even if it's
> as unspecific as Any.
>
> OOP, helping people be vague since, um..
>
> def ident[T](a: T)(b: T): Boolean ... should do it, because Scala's
> type parameter inference only looks at the first parameter list.
>
> 2009/6/9 Sciss :
>> stumpled again over the same problem.
>>
>> but this
>>
>> def ident[T]( a: T, b: T ) : Boolean = {
>> println( "Comparing a = " + a + "; with b = " + b )
>> a.equals( b )
>> }
>>
>> does not inforce a and b be of the same type... i don't understand
>> why?
>>
>> like i have
>>
>> val a: TypeA
>> val b: TypeB = TypeB.wrap( a )
>> implicit def bToA( x: TypeB ) : TypeA = { ... unwrap TypeA
>> which is
>> stored in TypeB ... }
>>
>> ident( a, b )
>> // --> false !!
>>
>> although bToA( b ) results in a.
>>
>> i'm confused....
>>
>> ciao, -sciss-
>>
>>
>>
>> Am 07.05.2009 um 02:22 schrieb Andrew O'Malley:
>>
>>> You might be interested in scalaz's Equal functionality:
>>> http://code.google.com/p/scalaz/source/browse/trunk/src/main/
>>> scala/scalaz/Equal.scala
>>>
>>> This defines an Equal trait that restricts the comparison to
>>> objects of
>>> the same type. Via implicits you can then compare objects using
>>> the "==="
>>> operator and will get the compiler errors you are after.
>>>
>>> On 07/05/2009, at 9:55 AM, Jorge Ortiz wrote:
>>>
>>>> Because Scala inherits == (and !=) from Java's "equals" method,
>>>> which
>>>> takes an Any as its argument.
>>>>
>>>> How do you prevent this mistake? Try findbugs
>>>> http://findbugs.sourceforge.net/
>>>>
>>>> --j
>>>>
>>>> On Wed, May 6, 2009 at 2:50 PM, Sciss wrote:
>>>> Hi,
>>>>
>>>> let's say i have a method
>>>>
>>>> class SplayTree[ T ]()( implicit view : (T) => Ordered[ T ])
>>>> extends scala.collection.mutable.Set[ T ] {
>>>>
>>>> ...
>>>>
>>>> def findMax: Option[ T ] = {
>>>> if( root == null ) return None
>>>> var x = root
>>>> while( x.right != null ) x = x.right
>>>> splay( x.elem )
>>>> Some( x.elem )
>>>> }
>>>>
>>>> ...
>>>> }
>>>>
>>>> and i am testing:
>>>>
>>>> val min = t.findMin
>>>> if( min != 2 ) {
>>>> println( "findMin error! Should be 2 but is " + min )
>>>> }
>>>>
>>>> why doesn't the compiler tell me that i'm having a type mismatch
>>>> ( if(
>>>> min != 2 ) compares an Option[ Int ] with an Int )? instead the
>>>> test fails
>>>> with printout:
>>>>
>>>> "findMin error! Should be 2 but is Some(2)"
>>>>
>>>> ... how can i avoid this problem?
>>>>
>>>> thanks, -sciss-
>>>>
>>>>
>>>>
>>>
>>
>>
Tue, 2009-06-09, 14:17
#8
Re: Why doesn't the compiler find this mistake...?
Ricky Clarkson schrieb:
> OOP, helping people be vague since, um..
1967. http://en.wikipedia.org/wiki/Simula
> def ident[T](a: T)(b: T): Boolean ... should do it, because Scala's
> type parameter inference only looks at the first parameter list.
Or tell it about the types you want. With these definitions:
case class TypeA(foo: Int)
case class TypeB(a: TypeA)
implicit def bToA(b: TypeB) = b.a
val a = TypeA(42)
val b= TypeB(a)
you get:
scala> ident(a, b)
Comparing a = TypeA(42); with b = TypeB(TypeA(42))
res0: Boolean = false
scala> ident[TypeA](a, b)
Comparing a = TypeA(42); with b = TypeA(42)
res1: Boolean = true
Your trick breaks reflexivity:
scala> ident(a)(b)
Comparing a = TypeA(42); with b = TypeA(42)
res2: Boolean = true
scala> ident(b)(a)
:13: error: type mismatch;
found : TypeA
required: TypeB
ident(b)(a)
^
- Florian.
Tue, 2009-06-09, 14:27
#9
Re: Why doesn't the compiler find this mistake...?
I was not aware that reflexivity was a requirement.
2009/6/9 Florian Hars :
> Ricky Clarkson schrieb:
>> OOP, helping people be vague since, um..
>
> 1967. http://en.wikipedia.org/wiki/Simula
>
>> def ident[T](a: T)(b: T): Boolean ... should do it, because Scala's
>> type parameter inference only looks at the first parameter list.
>
> Or tell it about the types you want. With these definitions:
>
> case class TypeA(foo: Int)
> case class TypeB(a: TypeA)
> implicit def bToA(b: TypeB) = b.a
>
> val a = TypeA(42)
> val b= TypeB(a)
>
> you get:
>
> scala> ident(a, b)
> Comparing a = TypeA(42); with b = TypeB(TypeA(42))
> res0: Boolean = false
>
> scala> ident[TypeA](a, b)
> Comparing a = TypeA(42); with b = TypeA(42)
> res1: Boolean = true
>
> Your trick breaks reflexivity:
>
> scala> ident(a)(b)
> Comparing a = TypeA(42); with b = TypeA(42)
> res2: Boolean = true
>
> scala> ident(b)(a)
> :13: error: type mismatch;
> found : TypeA
> required: TypeB
> ident(b)(a)
> ^
> - Florian.
>
How do you prevent this mistake? Try findbugs http://findbugs.sourceforge.net/
--j
On Wed, May 6, 2009 at 2:50 PM, Sciss <contact@sciss.de> wrote: