[Grace-core] [A Graceful Blog] Comment: "From Lancaster to Portland"

Andrew P. Black black at cs.pdx.edu
Wed Sep 28 22:18:53 PDT 2011


On 28 Sep 2011, at 20:15, John Tang Boyland wrote:

> 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) ?

I'm not clear if Dynamic should behave like None (statically conforms to any type, although dynamically may fail to do so, yielding an error) or Any (statically conforms to no type, and must be explicitly cast to a known type before it can be used in typed code).

Summarizing the above  (and adding the missing field accessors to the types)

GPointType = {x : Dynamic; y : Dynamic, equals (Dynamic) -> Boolean} 
SPointType = {x: Number; y: Number; equals (Any) -> Boolean}  

If Dynamic is like None, then SPointType does not conform to GPointType, because the result types of x and y don't conform.   So gp.equals(sp) will always answer false, regardless of the values of x and y.    Moreover, GPointType does not conforms to SPointType, because contravariance would require that Any conform to Dynamic.  So sp.equals(gp) will also always answer false.

Of course, if one wrote the "obvious" code 

SPointType = {x: Number; y: Number; = (SPointType) -> Boolean}  

class SPoint { x:Number, y:Number -> 
	method x: Number {x}
	method y: Number {y}
	method = (other:SPointType) -> Boolean {
		x = other.x & y = other.y
	}

then passing a GPoint as argument to = would work just fine.

	Andrew


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mailhost.cecs.pdx.edu/mailman/private/grace-core/attachments/20110928/4b6e531f/attachment.html>


More information about the Grace-core mailing list