www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - typedef: what's it good for?

reply Walter Bright <newshound1 digitalmars.com> writes:
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?
Nov 10 2009
next sibling parent BCS <none anon.com> writes:
Hello Walter,

 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?
 

I'd use them more if they were stronger. particularly, I'd love it if they could be used to add/overide stuff basic types: typedef int TD { TD opAdd(TD that) { assert(this < that); return cast(int)this + cast(int)that; } ... } or even better typedef int TD(T) { TD!(T) opAdd(TD!(T) that) if (Pred!(T)) = default; // use the default but restrict the operation ... }
Nov 10 2009
prev sibling next sibling parent reply Justin Johansson <no spam.com> writes:
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?

Early on (2 months ago) when I was just getting into D I asked about typedefs on this forum and some discussion transpired. http://www.digitalmars.com/d/archives/digitalmars/D/Is_typedef_an_alien_96658.html#N96658 (btw. There are a few responses from blasts from recent pasts in that thread.) Anyway, grepping for typedef over my current "scripting-language in D" project source shows only old versions of my project using typedefs. Accordingly it looks like I have since managed to convert *all* of my previous typedef incarnations to structs so as to take advantage of struct's support for static opCall so as to synthesize "constructors" (as well enabling use of struct methods). Maybe I didn't know enough about D back then, but the big problem with D typedefs (for me at least) was there was no support for typedef constructors and code otherwise blotted with cast-to-typedef-type is yuk in my way of thinking. I think there are only two sensible courses of action for D: support typedef constructors (and methods???) or remove 'em. I'm not sure which option I prefer (is the first even an option?) Cheers Justin Johansson
Nov 10 2009
next sibling parent reply rmcguire <rjmcguire gmail.com> writes:
Justin Johansson <no spam.com> wrote:
 
 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?

Early on (2 months ago) when I was just getting into D I asked about typedefs

 and some discussion transpired.
 
 http://www.digitalmars.com/d/archives/digitalmars/D/

 
 (btw. There are a few responses from blasts from recent pasts in that thread.)
 
 Anyway, grepping for typedef over my current "scripting-language in D" project 

 shows only old versions of my project using typedefs.  Accordingly it looks 

 since managed to convert *all* of my previous typedef incarnations to structs 

 take advantage of struct's support for static opCall so as to synthesize 

 (as well enabling use of struct methods).
 
 Maybe I didn't know enough about D back then, but the big problem with D 

 (for me at least) was there was no support for typedef constructors and code 

 blotted with cast-to-typedef-type is yuk in my way of thinking.
 
 I think there are only two sensible courses of action for D:  support typedef 

 (and methods???) or remove 'em.  I'm not sure which option I prefer (is the 

 an option?)
 
 Cheers
 Justin Johansson
 
 

I like typedef for making header files for c libraries. For example, so that you can't just pass an int to a function expecting an id.
Nov 11 2009
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
rmcguire wrote:
 Justin Johansson <no spam.com> wrote:
  
 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?


 and some discussion transpired.

 http://www.digitalmars.com/d/archives/digitalmars/D/

 (btw. There are a few responses from blasts from recent pasts in that thread.)

 Anyway, grepping for typedef over my current "scripting-language in D" project 

 shows only old versions of my project using typedefs.  Accordingly it looks 

 since managed to convert *all* of my previous typedef incarnations to structs 

 take advantage of struct's support for static opCall so as to synthesize 

 (as well enabling use of struct methods).

 Maybe I didn't know enough about D back then, but the big problem with D 

 (for me at least) was there was no support for typedef constructors and code 

 blotted with cast-to-typedef-type is yuk in my way of thinking.

 I think there are only two sensible courses of action for D:  support typedef 

 (and methods???) or remove 'em.  I'm not sure which option I prefer (is the 

 an option?)

 Cheers
 Justin Johansson

I like typedef for making header files for c libraries. For example, so that you can't just pass an int to a function expecting an id.

Today's typedef allows you to pass an arbitrary int literal as a typedef. typedef int ID; void fun(ID); fun(42); // compiles and runs Andrei
Nov 11 2009
prev sibling parent rmcguire <rjmcguire gmail.com> writes:
Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:
 
 rmcguire wrote:
 Justin Johansson <no spam.com> wrote:
  
 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?




 on this forum
 and some discussion transpired.

 http://www.digitalmars.com/d/archives/digitalmars/D/

 (btw. There are a few responses from blasts from recent pasts in that 



 Anyway, grepping for typedef over my current "scripting-language in D" 



 source
 shows only old versions of my project using typedefs.  Accordingly it looks 

 since managed to convert *all* of my previous typedef incarnations to 



 so as to
 take advantage of struct's support for static opCall so as to synthesize 

 (as well enabling use of struct methods).

 Maybe I didn't know enough about D back then, but the big problem with D 

 (for me at least) was there was no support for typedef constructors and code 

 blotted with cast-to-typedef-type is yuk in my way of thinking.

 I think there are only two sensible courses of action for D:  support 



 constructors 
 (and methods???) or remove 'em.  I'm not sure which option I prefer (is the 

 an option?)

 Cheers
 Justin Johansson

I like typedef for making header files for c libraries. For example, so that you can't just pass an int to a function expecting an id.

Today's typedef allows you to pass an arbitrary int literal as a typedef. typedef int ID; void fun(ID); fun(42); // compiles and runs Andrei

well then I also say its broken :)
Nov 11 2009
prev sibling next sibling parent =?ISO-8859-1?Q?Pelle_M=E5nsson?= <pelle.mansson gmail.com> writes:
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?

Nov 11 2009
prev sibling next sibling parent reply "Simen Kjaeraas" <simen.kjaras gmail.com> writes:
On Wed, 11 Nov 2009 07:45:26 +0100, BCS <none anon.com> wrote:

 Hello Walter,

 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?

I'd use them more if they were stronger. particularly, I'd love it if they could be used to add/overide stuff basic types: typedef int TD { TD opAdd(TD that) { assert(this < that); return cast(int)this + cast(int)that; } ... } or even better typedef int TD(T) { TD!(T) opAdd(TD!(T) that) if (Pred!(T)) = default; // use the default but restrict the operation ... }

We can already do that in D2: struct myInt { int _payload; alias _payload this; myInt opAdd( myInt that ) { assert( this._payload < that._payload ); return this._payload + that.payload; } } And I would believe this is why removing typedef is now being discussed. I like typedefs for when I need a separate type with no bells and whistles, and so suggest that typedef int foo; be kept as it is, and typedef int bar { /* stuffs */ } be sugar for struct bar { int _payload; alias _payload this; /* stuffs */ } -- Simen
Nov 11 2009
next sibling parent BCS <none anon.com> writes:
Hello Simen,

 [...] suggest that
 
 typedef int foo;
 
 be kept as it is, and
 
 typedef int bar {
 /* stuffs */
 }
 be sugar for
 
 struct bar {
 int _payload;
 alias _payload this;
 /* stuffs */
 }

One important aspect of what I proposed is that operators that aren't overridden still exist and use the same codegen as the base type (or are guarantied to generate the same machine code in all cases).
Nov 11 2009
prev sibling parent reply "Simen Kjaeraas" <simen.kjaras gmail.com> writes:
BCS <none anon.com> wrote:

 Hello Simen,

 [...] suggest that
  typedef int foo;
  be kept as it is, and
  typedef int bar {
 /* stuffs */
 }
 be sugar for
  struct bar {
 int _payload;
 alias _payload this;
 /* stuffs */
 }

One important aspect of what I proposed is that operators that aren't overridden still exist and use the same codegen as the base type (or are guarantied to generate the same machine code in all cases).

struct foo { float f; alias f this; } void main( ) { foo f; f = 3; f *= 4; f /= 8; f += 4/5; f -= sqrt( f ); } This compiles and runs beautifully, so it seems alias this does what you want. -- Simen
Nov 11 2009
parent BCS <none anon.com> writes:
Hello Simen,

 BCS <none anon.com> wrote:
 
 One important aspect of what I proposed is that operators that aren't
 overridden still exist and use the same codegen as the base type (or
 are  guarantied to generate the same machine code in all cases).
 

float f; alias f this; } void main( ) { foo f; f = 3; f *= 4; f /= 8; f += 4/5; f -= sqrt( f ); } This compiles and runs beautifully, so it seems alias this does what you want.

Hmm, I missed that bit. OTOH it still dosn't cover the "use the base ops but redefine the types" asspect. I so want that so that I can redo my Unit checking type with guarantied zero runtime overhead.
Nov 11 2009
prev sibling next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
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
Nov 11 2009
next sibling parent Bill Baxter <wbaxter gmail.com> writes:
On Wed, Nov 11, 2009 at 8:54 AM, Andrei Alexandrescu
<SeeWebsiteForEmail erdani.org> wrote:

 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.

Well put. I agree that typedef is nigh useless as is. I've tried to use it before, and just gave up because it seemed pretty clear that it was an alpha-level feature. --bb
Nov 11 2009
prev sibling next sibling parent "Adam D. Ruppe" <destructionator gmail.com> writes:
On Wed, Nov 11, 2009 at 10:54:27AM -0600, Andrei Alexandrescu wrote:
 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.:

I was thinking about this a while ago and had a half baked proposal, but ditched it exactly because it was half baked. My thought was to have two kinds of typedef: typedef int ID; // supertype typedef ID : int; // subtype - the syntax is based on class inheritance But I also kinda wanted no implicit conversion.... static typedef int ID; // :-P But however it is created, it would be useful for completely opaque types - useful for talking to C libraries. You can copy it, store it, and pass it around, but nothing else.
 Subtype vs. supertype is only the beginning of problems. Consider some 
 choice has been made, and then look at this orthogonal problem:

Disallow it. I don't think I've ever wanted to use typedef on anything other than primitives (and void*) anyway - structs and classes have their own ways to do the job. -- Adam D. Ruppe http://arsdnet.net
Nov 11 2009
prev sibling next sibling parent reply Matti Niemenmaa <see_signature for.real.address> writes:
Andrei Alexandrescu wrote:
 * typedef is hopelessly broken in very many ways
 
 * nobody noticed (i.e. no bugzilla reports), so probably nobody uses it

No Bugzilla reports? Here're just a few: http://d.puremagic.com/issues/show_bug.cgi?id=632 http://d.puremagic.com/issues/show_bug.cgi?id=1335 http://d.puremagic.com/issues/show_bug.cgi?id=1344 http://d.puremagic.com/issues/show_bug.cgi?id=1595 I use typedefs of integral types in one project, mostly because I read the D spec when I started out and thought it'd be a good idea, but because of 1335 and 1344 I eventually realized it wasn't such a good idea after all. I do still use them, but I wouldn't miss them much if they were gone.
Nov 11 2009
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Matti Niemenmaa wrote:
 Andrei Alexandrescu wrote:
 * typedef is hopelessly broken in very many ways

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

No Bugzilla reports? Here're just a few: http://d.puremagic.com/issues/show_bug.cgi?id=632 http://d.puremagic.com/issues/show_bug.cgi?id=1335 http://d.puremagic.com/issues/show_bug.cgi?id=1344 http://d.puremagic.com/issues/show_bug.cgi?id=1595 I use typedefs of integral types in one project, mostly because I read the D spec when I started out and thought it'd be a good idea, but because of 1335 and 1344 I eventually realized it wasn't such a good idea after all. I do still use them, but I wouldn't miss them much if they were gone.

Yeah sorry for exaggerating. I was mostly thinking that nobody seems to have noticed the problems with typedef for structs, built-in arrays, and pointers. Andrei
Nov 11 2009
prev sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Andrei Alexandrescu:

 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.

An usage of typedef: alias int[5][20] TyMat; typedef Mat TyMatA; typedef Mat TyMatB; Now a function can take both a TyMatA and TyMatB matrix, and the type system helps you to not confuse one for the other when you pass them around. If typedef gets removed from D, will the "typedef" keyword removed from the D language? Bye, bearophile
Nov 11 2009
next sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
bearophile wrote:
 Andrei Alexandrescu:
 
 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.

An usage of typedef: alias int[5][20] TyMat; typedef Mat TyMatA; typedef Mat TyMatB; Now a function can take both a TyMatA and TyMatB matrix, and the type system helps you to not confuse one for the other when you pass them around.

You may want to test what happens when you mix TyMatA and TyMatB in some operation.
 If typedef gets removed from D, will the "typedef" keyword removed from the D
language?

I would think so. Andrei
Nov 11 2009
prev sibling parent Walter Bright <newshound1 digitalmars.com> writes:
bearophile wrote:
 If typedef gets removed from D, will the "typedef" keyword removed from the D
language?

Eventually, yes, though there will be much time when it exists as a "deprecated" feature.
Nov 11 2009
prev sibling next sibling parent reply grauzone <none example.net> writes:
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 _actual_ use of typeof is to force a different array initializer (for performance reasons): typedef int Foo = 1; Foo[] arr; arr.length = 567; //with int[] arr, you now had to do arr[] = 1; Also, you can easily define new exception classes: //no need to write a ctor which just calls the super ctor typedef Exception MyException; But these are just symptoms of other problems of the language. Can typedef be the same as alias, if the current functionality goes?
Nov 11 2009
next sibling parent reply Bill Baxter <wbaxter gmail.com> writes:
On Wed, Nov 11, 2009 at 9:04 AM, grauzone <none example.net> wrote:
 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 _actual_ use of typeof is to force a different array initializer (for performance reasons): typedef int Foo = 1; Foo[] arr; arr.length = 567; //with int[] arr, you now had to do arr[] = 1; Also, you can easily define new exception classes: //no need to write a ctor which just calls the super ctor typedef Exception MyException;

Does this actually work now? Long ago this was one of the things I first thought I could use typedefs for, but it didn't work. I think it was because the compiler no longer recognizes MyException as a subtype of Exception anymore, but it was a long time ago, so I don't recall for sure. --bb
Nov 11 2009
parent grauzone <none example.net> writes:
Bill Baxter wrote:
 On Wed, Nov 11, 2009 at 9:04 AM, grauzone <none example.net> wrote:
 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?

performance reasons): typedef int Foo = 1; Foo[] arr; arr.length = 567; //with int[] arr, you now had to do arr[] = 1; Also, you can easily define new exception classes: //no need to write a ctor which just calls the super ctor typedef Exception MyException;

Does this actually work now? Long ago this was one of the things I first thought I could use typedefs for, but it didn't work. I think it was because the compiler no longer recognizes MyException as a subtype of Exception anymore, but it was a long time ago, so I don't recall for sure.

I think it does. There was a bug that prevented this from working, but it was fixed: http://d.puremagic.com/issues/show_bug.cgi?id=1285 Anyway, D should do something about those annoying ctors semantics. I propose we use exactly the same model as Object Pascal / Delphi did.
 --bb

Nov 11 2009
prev sibling parent dsimcha <dsimcha yahoo.com> writes:
== Quote from grauzone (none example.net)'s article
 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?

(for performance reasons):

Yes, but this is a **massive** kludge. The right answer is to allow custom array initializers. If this is the best we can come up with then typedef is really worthless.
Nov 11 2009
prev sibling parent Chad J <chadjoan __spam.is.bad__gmail.com> writes:
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?
 

A little.
 What do you use them for?
 

typedef uint ColorFormat; enum : ColorFormat { RGB, RGBA, HSV, CMYK, // etc } Now you have an enum that is type safe but doesn't require a qualified name to use. void convertToFormat( SomeTextureType someTexture, ColorFormat fmt ) { // etc } void main() { // ... auto foo = new SomeTextureType(...); convertToFormat(foo, 1); // Error, 1 is not a ColorFormat convertToFormat(foo, ColorFormat.RGBA ); // Nope convertToFormat(foo, RGBA); // This works. } Since ColorFormat is implicitly convertable to a uint, you should be able to use it as an array index to populate tables and such too.
 Do you need them?

Not really. It would be nice to have this kind of enum though. I think it was even mentioned in D con 2007 IIRC.
Nov 11 2009