[Grace-core] [A Graceful Blog] Comment: "From Lancaster to Portland"
John Tang Boyland
boyland at pabst.cs.uwm.edu
Wed Sep 28 20:15:30 PDT 2011
Dear James and Kim,
Thanks for your replies.
Kim's subtyping rules for S|T look fine; they don't look
particularly nominal or branded to me. You have:
U <: S OR U <: T => U <: (S|T)
S <: U AND T <: U => (S|T) <: U
Your rule for match requires that statically the object
being matched could be handled by at least one branch;
this seems sensible too. In your text, you say that
the only thing permitted with union types is match, but
of course, with subtyping and subsumption, other possibilities
exist. I may have read too much into that.
Regarding singleton types; this seems reasonable although as
Andrew Black reminded us, we need to know what equality is used to
compare the objects; value objects may use an overridden equal
which may cause interesting issues.
Regarding Gradual typing: I'm guessing you have a type Dynamic
which functions somewhat like a Top type except that it can always
be coerced into a static type with a runtime cast. And the cast
either fails right there or else we continue and if it fails later,
oops! (No proper blame.) Am I getting closer?
And if a type is omitted, Dynamic is inferred ?
So if I have a gradual class
class GPoint { x -> y ->
method equals(other) -> {
match(other) {
case { GPoint o -> o.x == x && o.y == y }
case { Object o -> false }
}
}
}
and a statically typed class
class SPoint { x:Number -> y : Number ->
method equals(other : Object) -> Boolean {
match(other) {
case { SPoint o -> o.x == x && o.y == y }
case { Object o -> false }
}
}
}
Suppose I have an instance gp of GPoint and sp of SPoint.
What happens if I do sp.equals(gp) ? or gp.equals(sp) ?
John
More information about the Grace-core
mailing list