internal const class Person
{
const Str? name
const Int? age
const Bool? canCode
new make(|This|? f := null) { if(f != null) {f(this)} }
override Bool equals(Obj? o)
{
if(o == null) return false
x := o as Person
if(x == null) return false
return (name == x.name && age == x.age && canCode == x.canCode)
}
override Int hash()
{
hash := 17
hash += hash*(name?.hash ?: 0)
hash += hash*(age?.hash ?: 0)
hash += hash*(canCode?.hash ?: 0)
return hash
}
override Str toStr()
{
return "Person{name:$name age:$age canCode:$canCode}"
}
}
If I replace
listType := List#.parameterize(["V":data.of])
type := Map#.parameterize(["K":Int#, "V":listType])
grPersons2:= Map.make(type)
with
grPersons2 := [Int:Persons[]][:]
It works fine. I even think that it gives 0 when comparing and that the hashes are equal. I'd love if there was some easier way to compare two maps/lists, but if I have to adhere to adhere to strong casting with verifyEq I'd at least would like to be able to be able to construct it dynamically.
brianTue 2 Aug 2011
Is the problem that using Type.paramaterize is not treating equality correctly?
Or just that you want a way to do equality in tests without worrying about list/map type?
DanielFathTue 2 Aug 2011
It's definitively former. Type.parameterize and/or equals (from the Map) isn't behaving properly. Both structures have same hash, contents and type signature and yet yield not equals. Something is fishy (I've looked at the content thoroughly and they are if I'm not mistaken same). I tried debugging it myself but I couldn't for the love of me, see what returned the false result - all I know is that some part of Map equals returns invalid result.
brianWed 3 Aug 2011
Renamed from Issue with equality to Type.parameterize equality bug
brianWed 3 Aug 2011
Promoted to ticket #1601 and assigned to brian
ok, will take a look
DanielFathSat 8 Oct 2011
Brian, I'm quite sorry about this one but it seems the type system was more complicated than I thought. Anyway my test is wrong.
listType := List#.parameterize(["V":data.of])
//Needs to be
listType := List#.parameterize(["V":data.of.params["V"]])
Here is the new test that causes error, I'm not sure if it is an error however...
**
** ** A test class for testing 'GROUP BY' statements
**
class GroupByTest : Test
{
internal static const Person[] persons :=
[
Person {name = "John"; age = 26; canCode = true},
Person {name = "Daniel"; age = 26; canCode = false},
Person {name = "Donovan"; age = 41; canCode = true}
]
Void testBasic()
{
grPersons:=
[
0 : [Person {name = "John"; age = 26; canCode = true}],
1 : [Person {name = "Daniel"; age = 26; canCode = false}],
2 : [Person {name = "Donovan"; age = 41; canCode = true}]
]
data:= persons
listType := List#.parameterize(["V":data.of] )
type := Map#.parameterize(["K":Int#, "V":listType])
[Obj:Obj[]]? retVal := Map.make(type)
i := 0
x:= retVal.containsKey(0)
data.size.times
{
if(!retVal.containsKey(i))
{
retVal.add(i, [,])
}
list := retVal[i++]
list.add(data[it])
}
verifyEq(retVal, select)
verifyEq(select.typeof, grPersons.typeof)
verifyEq(select, grPersons)
}
static [Int:Person[]] select()
{
data:= persons
listType := List#.parameterize(["V":data.of] )
type := Map#.parameterize(["K":Int#, "V":listType])
[Obj:Obj[]]? retVal := Map.make(type)
i := 0
x:= retVal.containsKey(0)
data.size.times
{
if(!retVal.containsKey(i))
{
retVal.add(i, [,])
}
list := retVal[i++]
list.add(data[it])
}
return retVal
}
}
From what I've seen the problem is when that if List passes throught a method it loses some of its type signatures. The first two verify will pass, only third will fail.
EDIT: Error occurs somewhere in Map.java. How do I debug that?
brianSat 8 Oct 2011
The maps are not equal because their items are not equal. The items are not equal because the inferred type in grPersons is that each list is Person[], but in your select method are creating generic Obj?[] lists:
// create Obj?[]
retVal.add(i, [,])
// should be
retVal.add(i, Person[,])
Remember that in the end each value of map of list is checked for equality.
So I don't think there is any problem here?
DanielFathSat 8 Oct 2011
Hmm. Yeah I missed that one list. Tnx for debugging for me :P.
Case closed. It was my error. Still for reference how do you guys debug the Java native/peer clases? You use System.out or could I use Fantom's logger?
brianSun 9 Oct 2011
Ticket cancelled
Still for reference how do you guys debug the Java native/peer clases
I debug all my code using echo/System.out.println - although virtually all my debugging is spent in test suite itself.
DanielFath Tue 2 Aug 2011
And the Person class just for record.
If I replace
with
It works fine. I even think that it gives 0 when comparing and that the hashes are equal. I'd love if there was some easier way to compare two maps/lists, but if I have to adhere to adhere to strong casting with
verifyEq
I'd at least would like to be able to be able to construct it dynamically.brian Tue 2 Aug 2011
Is the problem that using Type.paramaterize is not treating equality correctly?
Or just that you want a way to do equality in tests without worrying about list/map type?
DanielFath Tue 2 Aug 2011
It's definitively former.
Type.parameterize
and/orequals
(from the Map) isn't behaving properly. Both structures have same hash, contents and type signature and yet yield not equals. Something is fishy (I've looked at the content thoroughly and they are if I'm not mistaken same). I tried debugging it myself but I couldn't for the love of me, see what returned the false result - all I know is that some part of Map equals returns invalid result.brian Wed 3 Aug 2011
Renamed from Issue with equality to Type.parameterize equality bug
brian Wed 3 Aug 2011
Promoted to ticket #1601 and assigned to brian
ok, will take a look
DanielFath Sat 8 Oct 2011
Brian, I'm quite sorry about this one but it seems the type system was more complicated than I thought. Anyway my test is wrong.
PS. I still managed to get this error:
Which looks odd.
DanielFath Sat 8 Oct 2011
Here is the new test that causes error, I'm not sure if it is an error however...
From what I've seen the problem is when that if List passes throught a method it loses some of its type signatures. The first two verify will pass, only third will fail.
EDIT: Error occurs somewhere in Map.java. How do I debug that?
brian Sat 8 Oct 2011
The maps are not equal because their items are not equal. The items are not equal because the inferred type in grPersons is that each list is Person[], but in your
select
method are creating genericObj?[]
lists:Remember that in the end each value of map of list is checked for equality.
So I don't think there is any problem here?
DanielFath Sat 8 Oct 2011
Hmm. Yeah I missed that one list. Tnx for debugging for me :P.
Case closed. It was my error. Still for reference how do you guys debug the Java native/peer clases? You use
System.out
or could I use Fantom's logger?brian Sun 9 Oct 2011
Ticket cancelled
I debug all my code using echo/System.out.println - although virtually all my debugging is spent in test suite itself.