[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