typedef

Andrei Alexandrescu SeeWebsiteForEmail at erdani.org
Fri Mar 6 09:47:40 PST 2009


I tried typedef in two instances, to sadly conclude that it's not useful 
as a true abstraction mechanism. The good news is that it's very close 
to being useful.

Ideally, typedef should provide a completely parallel type with the type 
under the typedef, as if you sat down and wrote it from scratch. 
Unfortunately, today typedef is just about equivariant with the type it 
comes from:

void main()
{
     typedef int IDType;
     IDType id = 5;
     int x = id;
}

This compiles and runs flag-free. An IDType accepts any int without any 
fuss, and furthermore an int accepts an IDType no problem. As such, 
typedef introduces neither a supertype nor a subtype of int.

I believe this behavior is unhelpful as it prevents IDType from being a 
true abstraction mechanism. What should happen is that only this should 
compile:

void main()
{
     typedef int IDType;
     auto id = IDType(5);
     int x = id;
}

So the literals of type IDType have the form IDType(n). That way it's 
visible that we want to deal in IDType objects. I think it's ok that the 
int can be be teased out of an IDType without an explicit conversion. 
Requiring a cast would be a tad too rigid. So with the new rules in 
place we defined a sort of subtype of int.

This works even better with classes. Consider exceptions for instance:

typedef Exception MyException;

void main()
{
     try
     {
         throw new MyException("x");
     }
     catch(MyException e) { writeln("a"); }
     catch (Exception e)  { writeln("b"); }
}

This code doesn't compile with:

Error: catch at ./test.d(19) hides catch at ./test.d(20)

So to the compiler typedefs are today too much the same as the source type.


Andrei



More information about the Digitalmars-d mailing list