[Grace-core] talking generics with Gilad over lunch

James Noble kjx at ecs.vuw.ac.nz
Wed Oct 30 14:51:41 PDT 2013


> You're already doing it that way. That is exactly the semantics of gradual runtime checks now.

OK, so that's something.
I mean it's a change to the spec if not a change to the implementation.

>> - what are the problems (slowdown, obviously)?
> It's not obviously slower. There's no reason that a sufficiently
> clever compiler can't optimise out the dynamic checks if it determines
> they can never fail by static analysis, but otherwise it has to do the
> same checks regardless.

right.

>> - how much type-style syntax do we want to keep?
> All of it. Type definitions would dynamically construct patterns, as
> now, and a static dialect could interpret them and examine the program
> to generate errors, as now. Type patterns get privileged access to
> examine objects, so they are still special.

I think we do need to keep the (x  : y) syntax on arguments and the -> syntax on return values.

I can't remember if  "e:T" aka "e:p" is an expression, but it could be with the semantic
   assert (T.match(myValue)) description "type error"
or not. 

>> - this gives us the option of seamlessly incorporating much more into dynamic "types"
>>          e.g. X10 style constrained types: subranges, non-zero, even numbers etc
> These would be good (but can easily be prohibited by a dialect).

well yeah.  perhaps we can haul Dave in?

>> - if we want one definition for both generic & nongeneric classes,
>>      we still have to make the "type" argument optional somehow...
>>          [this leads to a rabbit hole, down which I am often tempted to jump]
> This is already the only option now.

right, but I guess the point is they are special cased to be optional.  and we have to have them.

or we could do something like this 

def Map = 
  class MapClass.from (Key: Type) to (Value: Type) { 
    // map class goes here
  }
  method newFrom(Key: Type) to (Value: Type) { MapClass.from(Key) to (Value) }
  method new (MapClass.from(Key) to (Value)}
}

if we had my "generalised requests" we could write 

class MapClass.from (Key: Type = Dynamic) to (Value: Type = Dynamic) { 
    // map class goes here
}

and get pretty much what we want.   The main issue being people calling "new"
and getting the dynamically typed (equivalent to Java's raw typed) version from
typed code.  Yes checkers could check, but perhaps we'd have to add
annotations or something to say "this method doesn't stick in gratuitous dynamics". 
That gets harder that if type arguments are syntatically (and semantically?) special.


The reason to advocate for this is that "generalised requests"
could also help with things like match()case() etc. 

method match(t : Target) | *case( cases: Block) 




>> - how does this play with other annotations?
>> - do we need e.g. a "pure" annotation on methods / patterns / types? -
> Yes, but unrelated to this.

I guess "types" could be distinguished from "patterns" because types messages are pure -
at least if we want to inline / propagate checks, it's easier if they're pure. 

>> [PS - Michael: prior to this conversation, I have been thinking about inference for reified types,
>> and I think you're probably right - we should try sticking with your design: no inference,]
> Of course.

cheers! 

J


More information about the Grace-core mailing list