Walter Bright wrote:
When I originally worked out ideas for D, there were many requests from the C and C++ community for a 'strong' typedef, and so I put one in D. I didn't think about it too much, just assumed that it was a good idea.

Now I'm not so sure. Maybe it should be removed for D2.

Does anyone use typedef's?

What do you use them for?

Do you need them?

One good way to figure out how well-defined something is would be to attempt explaining it to someone. That's what happened as I was writing about typedef in TDPL. I realized the following:

* typedef is hopelessly broken in very many ways

* nobody noticed (i.e. no bugzilla reports), so probably nobody uses it

* fixing it to do anything remotely useful would be a major effort and would complicate the language

* even if fixed to do something useful, the usefulness would be very limited

* it's unclear which of two different fixes would make it more useful and less confusing

The last point was revealed by a conversation between Walter and me last night. I pointed out that typedef should create a *subtype* of a type, e.g.:

typedef int ID;
ID id;
int x;
id = x; // no
x = id; // yes

He pointed out that typedef should create a *supertype*, e.g.:

typedef int ID;
ID id;
int x;
id = x; // yes
x = id; // no

I still think that subtype would be a better choice than supertype, but I also could see cases in which you want the supertype case. So I expect that whatever we choose, some may expect the opposite and get confused.

One alternative is to make typedef a completely separate type, with explicit casts:

typedef int ID;
ID id;
int x;
id = x;      // no
x = id;      // no
id = ID(x);  // yes
x = int(id); // yes

Then everybody would complain that the "right" direction is not implicit.

Subtype vs. supertype is only the beginning of problems. Consider some choice has been made, and then look at this orthogonal problem:

struct A {
   A foo();
   void bar(A);
   A baz(A);
}
typedef A B;

What should that do? After much thinking, I concluded the most reasonable thing it could do is to replace A with B throughout the definition, e.g.:

struct B {
   B foo();
   void bar(B);
   B baz(B);
}

I found some examples for the usefulness of that, but then also examples in which some or all of those functions should use an A sometimes.

Today, typedef does essentially nothing notable or even correct and consistent for structs, classes, pointers, and arrays. It even has some egregious errors, for example when defining binary operators. Nobody noticed them probably because nobody used them.

Walter's and my interim conclusion last night was that fixing typedef would be difficult, and that the usefulness of typedef is too little for its complexity. It may be a good idea to just remove it from the language. We already have a host of other abstraction-building mechanisms, and typedef does not seem to build a good abstraction.


Andrei

Reply via email to