digitalmars.D - need clarification: will typedef, C struct initialization, etc. go or not?
- Trass3r (6/6) May 17 2010 There have been lots of discussions about removing language parts.
- Kagamin (1/1) May 17 2010 And this should go into docs.
- Trass3r (1/2) May 18 2010 True.
- Trass3r (1/5) May 31 2010 Nobody got an answer?
- bearophile (7/8) May 31 2010 My opinion:
- Andrei Alexandrescu (3/9) May 31 2010 typedef is gone.
- bearophile (4/5) May 31 2010 *mewls* I have shown here some examples of typedef usage, and I'll keep ...
- Adam Ruppe (24/31) May 31 2010 Doesn't
- Andrei Alexandrescu (5/10) May 31 2010 Exactly. And with alias this and other mechanisms, you can define
- Andrei Alexandrescu (3/6) May 31 2010 It's wasted time. typedef is gone.
- Lionello Lunesu (17/28) May 31 2010 :((
- Justin Spahr-Summers (5/31) May 31 2010 I'm a fan of typedef, personally, but the example you mentioned *would*
- Leandro Lucarella (24/56) May 31 2010 I think he talks about this difference:
- Justin Spahr-Summers (4/54) May 31 2010 Understood, but he mentioned translating C headers. D's 'typedef' has no...
- Lionello Lunesu (4/59) Jun 01 2010 Where does it say that translated headers cannot be better than the
- Kagamin (2/18) Jun 01 2010 windows handles are not orthogonal, they're polymorphic. For example, Cl...
- Lionello Lunesu (7/26) Jun 01 2010 OK, so I can pass any handle to CloseHandle, but that doesn't mean I can
- Trass3r (2/11) May 31 2010 Seconded. Using it often for C wrappers.
- Simen kjaeraas (9/23) May 31 2010 struct Typedef( T ) {
- Andrei Alexandrescu (5/30) May 31 2010 Yah, perfect - that would be the subtype. I think we should work on
- Lionello Lunesu (6/43) Jun 01 2010 Super/sub is of minor importance. What's important is that siblings are
- Simen kjaeraas (72/83) Jun 02 2010 Actually, alias this makes it more of a parallel type.
-
Adam Ruppe
(12/12)
Jun 02 2010
On 6/2/10, Simen kjaeraas
wrote: - Simen kjaeraas (16/28) Jun 02 2010 My code sidesteps that by including instantiation line and file,
- Adam Ruppe (1/1) Jun 02 2010 How cool! I like that a lot.
- bearophile (5/8) Jun 02 2010 Cute :-)
- Lars T. Kyllingstad (3/26) Jun 02 2010 Cool trick! :)
- Lionello Lunesu (6/35) Jun 03 2010 Cool trick indeed, but why do we need a trick for something so basic!?
- bearophile (5/6) Jun 03 2010 For that a gensym is better than the date/file pair. But a gensym() desp...
- Adam Ruppe (10/12) Jun 03 2010 Do you consider ALL library solutions to be "hacks"? It sure seems
- Andrei Alexandrescu (5/17) Jun 03 2010 Agreed. The reality was that typedef was in fact a hack; its semantics
- bearophile (9/11) Jun 03 2010 I have seen some situations where library solutions are not good enough ...
- Adam Ruppe (39/60) Jun 03 2010 When it comes to code accessibility, the compiler is a black box. You
- bearophile (7/13) Jun 03 2010 I think I have never put two typedefs on one line, but hidden traps are ...
- retard (2/25) Jun 03 2010 Don't forget machine generated code. E.g. CTFE or parser generators
- Lionello Lunesu (11/13) Jun 04 2010 struct Typedef( T, T init = T.init, Type type = Type.Sub, string _f =
- Andrei Alexandrescu (34/46) Jun 04 2010 The problem is, there's not only one good use. Walter and I identified
- Trass3r (1/7) May 31 2010 The question is if this still works flawlessly for complicated examples.
- Lars T. Kyllingstad (24/53) Jun 01 2010 Nice. :) But it isn't quite a typedef, because if you do
- Ellery Newcomer (2/7) May 31 2010 user specified T.init?
- Lionello Lunesu (2/3) May 31 2010 I love(d) that feature!
- Lutger (2/17) Jun 06 2010 struct initializers are gone too?
- Andrei Alexandrescu (4/21) Jun 06 2010 You mean { }? I seem to remember Walter mentioned they are no longer
- Ellery Newcomer (2/27) Jun 06 2010 Ooo Ooo Ooo Can we get rid of them? Pretty pretty please?
- bearophile (5/6) Jun 06 2010 Why are you so eager to remove them?
- Ellery Newcomer (8/14) Jun 06 2010 because they're difficult to disambiguate from function literals (at
There have been lots of discussions about removing language parts. I don't want this thread to become yet another one. I just want to know if (and when) these features will be removed or not. Especially typedef, which I found quite useful lately. C-style struct initialization and complex types have also been discussed but are still in.
May 17 2010
I just want to know if (and when) these features will be removed or not. Especially typedef, which I found quite useful lately. C-style struct initialization and complex types have also been discussed but are still in.Nobody got an answer?
May 31 2010
Trass3r:Nobody got an answer?My opinion: - complex types will be removed. And as far as I know complex number literals too will be removed from D (this is less nice). - I am not sure regarding C-style struct initializations. They are useful to save some typing if you have to for example to put a long array of struct literals in your source code. I presume they will be removed. - Typedef has some limitations, but I think it will be kept because it is useful. Bye, bearophile
May 31 2010
On 05/31/2010 02:14 PM, bearophile wrote:Trass3r:typedef is gone. AndreiNobody got an answer?My opinion: - complex types will be removed. And as far as I know complex number literals too will be removed from D (this is less nice). - I am not sure regarding C-style struct initializations. They are useful to save some typing if you have to for example to put a long array of struct literals in your source code. I presume they will be removed. - Typedef has some limitations, but I think it will be kept because it is useful.
May 31 2010
Andrei Alexandrescu:typedef is gone.*mewls* I have shown here some examples of typedef usage, and I'll keep posting few more in future. I'd like to pull it back from the grave and keep it :-) Bye, bearophile
May 31 2010
Doesn't struct T { R _payload; } accomplish the same thing as typedef R T; in the majority of useful cases? I use typedef void* Some_C_Type; a lot, and rather like it for a handful of other things, but I'm pretty sure the struct accomplishes the same thing in those cases. As a template in the stdlib (std.typecons surely), it could be done easily enough in user code The immediate differences are casting doesn't work the same* and the compiler error messages aren't as good**. But these are minor, and might be caused solely by my poor implementation. * I used struct Typedef(R) { R _base; } alias Typedef!int Handle; Casting: Error: e2ir: cannot cast a of type Typedef!(int) to type int. Though, Handle a; a._base; would do the trick, just not be consistent. ** Using the above: void foo(T) { } foo(10); // cannot implicitly convert expression (10) of type int to Typedef!(int) Might be nice if it showed the alias name. This is something that might be generally useful if changed, so it could improve other things unlike the specialized feature. On 5/31/10, bearophile <bearophileHUGS lycos.com> wrote:Andrei Alexandrescu:typedef is gone.*mewls* I have shown here some examples of typedef usage, and I'll keep posting few more in future. I'd like to pull it back from the grave and keep it :-) Bye, bearophile
May 31 2010
On 05/31/2010 04:11 PM, Adam Ruppe wrote:Doesn't struct T { R _payload; } accomplish the same thing as typedef R T; in the majority of useful cases?Exactly. And with alias this and other mechanisms, you can define several well-defined typedef incarnations that achieve what you want to express. Andrei
May 31 2010
On 05/31/2010 03:54 PM, bearophile wrote:Andrei Alexandrescu:It's wasted time. typedef is gone. Andreitypedef is gone.*mewls* I have shown here some examples of typedef usage, and I'll keep posting few more in future. I'd like to pull it back from the grave and keep it :-)
May 31 2010
On 1-6-2010 5:38, Andrei Alexandrescu wrote:On 05/31/2010 03:54 PM, bearophile wrote::(( I also miss typedef. I thought D had a great opportunity to fix it. Take something like the Windows headers. It mostly consists of typedefs for handles and whatnot. Without typedef you'd have to use alias and type safety is out of the windows. So what would be the way to translate those Windows headers? Create a unique struct for each old typedef? With alias this, and a ctor? Well, if that's the way to do it now, why not make typedef a shortcut for exactly that!? IIRC typedef is gone because you and Walter could not agree whether it had to be a subtype or a supertype of the typedef'ed type. For me it's rather simple: I want to introduce a new type in such a way that it helps me prevent mistakes, ie. passing one handle when the function wants another, even though both are based on void*, or whatever. Bring typedef back! L.Andrei Alexandrescu:It's wasted time. typedef is gone. Andreitypedef is gone.*mewls* I have shown here some examples of typedef usage, and I'll keep posting few more in future. I'd like to pull it back from the grave and keep it :-)
May 31 2010
On Tue, 01 Jun 2010 06:05:50 +0800, Lionello Lunesu <lio lunesu.remove.com> wrote:On 1-6-2010 5:38, Andrei Alexandrescu wrote:I'm a fan of typedef, personally, but the example you mentioned *would* be solved using just an alias. 'alias' provides the same functionality as C/C++'s 'typedef' and more.On 05/31/2010 03:54 PM, bearophile wrote::(( I also miss typedef. I thought D had a great opportunity to fix it. Take something like the Windows headers. It mostly consists of typedefs for handles and whatnot. Without typedef you'd have to use alias and type safety is out of the windows. So what would be the way to translate those Windows headers? Create a unique struct for each old typedef? With alias this, and a ctor? Well, if that's the way to do it now, why not make typedef a shortcut for exactly that!?Andrei Alexandrescu:It's wasted time. typedef is gone. Andreitypedef is gone.*mewls* I have shown here some examples of typedef usage, and I'll keep posting few more in future. I'd like to pull it back from the grave and keep it :-)
May 31 2010
Justin Spahr-Summers, el 31 de mayo a las 16:41 me escribiste:On Tue, 01 Jun 2010 06:05:50 +0800, Lionello Lunesu <lio lunesu.remove.com> wrote:I think he talks about this difference: alias int a1; alias int a2; typedef int t1; typedef int t2; void fa(a2 a) {} void ft(t2 t) {} void main() { a1 a = 5; fa(a); // <--- compiles fine t1 t = 10; ft(t); // <--- error } function a.ft (t2) does not match parameter types (t1) types (t1) cannot implicitly convert expression (t) of type t1 to t2 Alias does not provide type-safety. -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ ---------------------------------------------------------------------- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) ---------------------------------------------------------------------- There is no such thing as right or wrong Only consequencesOn 1-6-2010 5:38, Andrei Alexandrescu wrote:I'm a fan of typedef, personally, but the example you mentioned *would* be solved using just an alias. 'alias' provides the same functionality as C/C++'s 'typedef' and more.On 05/31/2010 03:54 PM, bearophile wrote::(( I also miss typedef. I thought D had a great opportunity to fix it. Take something like the Windows headers. It mostly consists of typedefs for handles and whatnot. Without typedef you'd have to use alias and type safety is out of the windows. So what would be the way to translate those Windows headers? Create a unique struct for each old typedef? With alias this, and a ctor? Well, if that's the way to do it now, why not make typedef a shortcut for exactly that!?Andrei Alexandrescu:It's wasted time. typedef is gone. Andreitypedef is gone.*mewls* I have shown here some examples of typedef usage, and I'll keep posting few more in future. I'd like to pull it back from the grave and keep it :-)
May 31 2010
On Mon, 31 May 2010 23:31:18 -0300, Leandro Lucarella <llucax gmail.com> wrote:Justin Spahr-Summers, el 31 de mayo a las 16:41 me escribiste:Understood, but he mentioned translating C headers. D's 'typedef' has no ready equivalent in C or C++.On Tue, 01 Jun 2010 06:05:50 +0800, Lionello Lunesu <lio lunesu.remove.com> wrote:I think he talks about this difference: alias int a1; alias int a2; typedef int t1; typedef int t2; void fa(a2 a) {} void ft(t2 t) {} void main() { a1 a = 5; fa(a); // <--- compiles fine t1 t = 10; ft(t); // <--- errorOn 1-6-2010 5:38, Andrei Alexandrescu wrote:I'm a fan of typedef, personally, but the example you mentioned *would* be solved using just an alias. 'alias' provides the same functionality as C/C++'s 'typedef' and more.On 05/31/2010 03:54 PM, bearophile wrote::(( I also miss typedef. I thought D had a great opportunity to fix it. Take something like the Windows headers. It mostly consists of typedefs for handles and whatnot. Without typedef you'd have to use alias and type safety is out of the windows. So what would be the way to translate those Windows headers? Create a unique struct for each old typedef? With alias this, and a ctor? Well, if that's the way to do it now, why not make typedef a shortcut for exactly that!?Andrei Alexandrescu:It's wasted time. typedef is gone. Andreitypedef is gone.*mewls* I have shown here some examples of typedef usage, and I'll keep posting few more in future. I'd like to pull it back from the grave and keep it :-)
May 31 2010
On 1-6-2010 12:05, Justin Spahr-Summers wrote:On Mon, 31 May 2010 23:31:18 -0300, Leandro Lucarella <llucax gmail.com> wrote:Where does it say that translated headers cannot be better than the original? :) L.Justin Spahr-Summers, el 31 de mayo a las 16:41 me escribiste:Understood, but he mentioned translating C headers. D's 'typedef' has no ready equivalent in C or C++.On Tue, 01 Jun 2010 06:05:50 +0800, Lionello Lunesu <lio lunesu.remove.com> wrote:I think he talks about this difference: alias int a1; alias int a2; typedef int t1; typedef int t2; void fa(a2 a) {} void ft(t2 t) {} void main() { a1 a = 5; fa(a); // <--- compiles fine t1 t = 10; ft(t); // <--- errorOn 1-6-2010 5:38, Andrei Alexandrescu wrote:I'm a fan of typedef, personally, but the example you mentioned *would* be solved using just an alias. 'alias' provides the same functionality as C/C++'s 'typedef' and more.On 05/31/2010 03:54 PM, bearophile wrote::(( I also miss typedef. I thought D had a great opportunity to fix it. Take something like the Windows headers. It mostly consists of typedefs for handles and whatnot. Without typedef you'd have to use alias and type safety is out of the windows. So what would be the way to translate those Windows headers? Create a unique struct for each old typedef? With alias this, and a ctor? Well, if that's the way to do it now, why not make typedef a shortcut for exactly that!?Andrei Alexandrescu:It's wasted time. typedef is gone. Andreitypedef is gone.*mewls* I have shown here some examples of typedef usage, and I'll keep posting few more in future. I'd like to pull it back from the grave and keep it :-)
Jun 01 2010
Leandro Lucarella Wrote:I think he talks about this difference: alias int a1; alias int a2; typedef int t1; typedef int t2; void fa(a2 a) {} void ft(t2 t) {} void main() { a1 a = 5; fa(a); // <--- compiles fine t1 t = 10; ft(t); // <--- error }windows handles are not orthogonal, they're polymorphic. For example, CloseHandle function accepts almost any handle.
Jun 01 2010
On 1-6-2010 18:04, Kagamin wrote:Leandro Lucarella Wrote:OK, so I can pass any handle to CloseHandle, but that doesn't mean I can pass any handle like any other handle. And not all typedefs in the Windows headers behave that way, some are not compatible with anything else. Don't focus too much on my Windows header example. It was just that, an example. L.I think he talks about this difference: alias int a1; alias int a2; typedef int t1; typedef int t2; void fa(a2 a) {} void ft(t2 t) {} void main() { a1 a = 5; fa(a); // <--- compiles fine t1 t = 10; ft(t); // <--- error }windows handles are not orthogonal, they're polymorphic. For example, CloseHandle function accepts almost any handle.
Jun 01 2010
So what would be the way to translate those Windows headers? Create a unique struct for each old typedef? With alias this, and a ctor? Well, if that's the way to do it now, why not make typedef a shortcut for exactly that!?Yeah there must be some short and clean way to define it.IIRC typedef is gone because you and Walter could not agree whether it had to be a subtype or a supertype of the typedef'ed type. For me it's rather simple: I want to introduce a new type in such a way that it helps me prevent mistakes, ie. passing one handle when the function wants another, even though both are based on void*, or whatever.Seconded. Using it often for C wrappers.
May 31 2010
Lionello Lunesu <lio lunesu.remove.com> wrote:I also miss typedef. I thought D had a great opportunity to fix it. Take something like the Windows headers. It mostly consists of typedefs for handles and whatnot. Without typedef you'd have to use alias and type safety is out of the windows. So what would be the way to translate those Windows headers? Create a unique struct for each old typedef? With alias this, and a ctor? Well, if that's the way to do it now, why not make typedef a shortcut for exactly that!? IIRC typedef is gone because you and Walter could not agree whether it had to be a subtype or a supertype of the typedef'ed type. For me it's rather simple: I want to introduce a new type in such a way that it helps me prevent mistakes, ie. passing one handle when the function wants another, even though both are based on void*, or whatever. Bring typedef back!struct Typedef( T ) { T payload; alias payload this; } alias Typedef!int myInt; There you go. -- Simen
May 31 2010
On 05/31/2010 10:07 PM, Simen kjaeraas wrote:Lionello Lunesu <lio lunesu.remove.com> wrote:Yah, perfect - that would be the subtype. I think we should work on adding a pseudo-supertype as well, and also on a completely independent type. Then we can add these abstractions to std.typecons. AndreiI also miss typedef. I thought D had a great opportunity to fix it. Take something like the Windows headers. It mostly consists of typedefs for handles and whatnot. Without typedef you'd have to use alias and type safety is out of the windows. So what would be the way to translate those Windows headers? Create a unique struct for each old typedef? With alias this, and a ctor? Well, if that's the way to do it now, why not make typedef a shortcut for exactly that!? IIRC typedef is gone because you and Walter could not agree whether it had to be a subtype or a supertype of the typedef'ed type. For me it's rather simple: I want to introduce a new type in such a way that it helps me prevent mistakes, ie. passing one handle when the function wants another, even though both are based on void*, or whatever. Bring typedef back!struct Typedef( T ) { T payload; alias payload this; } alias Typedef!int myInt; There you go.
May 31 2010
On 1-6-2010 11:37, Andrei Alexandrescu wrote:On 05/31/2010 10:07 PM, Simen kjaeraas wrote:Super/sub is of minor importance. What's important is that siblings are incompatible. That's impossible now with alias and Simen's TypeDef doesn't solve it either. Typedef was the perfect candidate for it. That, and the custom .init! :o) L.Lionello Lunesu <lio lunesu.remove.com> wrote:Yah, perfect - that would be the subtype. I think we should work on adding a pseudo-supertype as well, and also on a completely independent type. Then we can add these abstractions to std.typecons. AndreiI also miss typedef. I thought D had a great opportunity to fix it. Take something like the Windows headers. It mostly consists of typedefs for handles and whatnot. Without typedef you'd have to use alias and type safety is out of the windows. So what would be the way to translate those Windows headers? Create a unique struct for each old typedef? With alias this, and a ctor? Well, if that's the way to do it now, why not make typedef a shortcut for exactly that!? IIRC typedef is gone because you and Walter could not agree whether it had to be a subtype or a supertype of the typedef'ed type. For me it's rather simple: I want to introduce a new type in such a way that it helps me prevent mistakes, ie. passing one handle when the function wants another, even though both are based on void*, or whatever. Bring typedef back!struct Typedef( T ) { T payload; alias payload this; } alias Typedef!int myInt; There you go.
Jun 01 2010
Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Actually, alias this makes it more of a parallel type. This code, however, allows for subtypes, supertypes, parallel types, as well as independent types. please critique. enum Type { Independent, Super, Sub, Parallel, } struct Typedef( T, T init = T.init, Type type = Type.Sub, string _f = __FILE__, int _l = __LINE__ ) { T payload = init; static if ( type != Type.Independent ) { this( T value ) { payload = value; } } static if ( type == Type.Sub || type == Type.Parallel ) { alias payload this; } static if ( type == Type.Super ) { typeof( this ) opAssign( T value ) { payload = value; return this; } } else static if ( type == Type.Sub ) { disable void opAssign( T value ); } } unittest { alias Typedef!( int, 1, Type.Super ) superInt; alias Typedef!( int, 2, Type.Sub ) subInt; alias Typedef!( int, 3, Type.Independent ) independentInt; alias Typedef!( int, 3, Type.Parallel ) parallelInt; int i; superInt m1; subInt m2; independentInt m3; parallelInt m4; // Construct static assert( is( typeof({ superInt j = i; }))); static assert( is( typeof({ subInt j = i; }))); static assert( !is( typeof({ IndependentInt j = i; }))); static assert( is( typeof({ parallelInt j = i; }))); // Assign from base static assert( is( typeof({ m1 = i; }))); static assert( !is( typeof({ m2 = i; }))); static assert( !is( typeof({ m3 = i; }))); static assert( is( typeof({ m4 = i; }))); // Assign to base static assert( !is( typeof({ i = m1; }))); static assert( is( typeof({ i = m2; }))); static assert( !is( typeof({ i = m3; }))); static assert( is( typeof({ i = m4; }))); // Assign from other type static assert( is( typeof({ m1 = m2; }))); static assert( !is( typeof({ m2 = m1; }))); static assert( !is( typeof({ m1 = m3; }))); static assert( !is( typeof({ m2 = m3; }))); static assert( !is( typeof({ m3 = m1; }))); static assert( !is( typeof({ m3 = m2; }))); static assert( is( typeof({ m1 = m4; }))); static assert( !is( typeof({ m2 = m4; }))); static assert( !is( typeof({ m3 = m4; }))); static assert( !is( typeof({ m4 = m1; }))); static assert( is( typeof({ m4 = m2; }))); static assert( !is( typeof({ m4 = m3; }))); } -- Simenstruct Typedef( T ) { T payload; alias payload this; } alias Typedef!int myInt; There you go.Yah, perfect - that would be the subtype. I think we should work on adding a pseudo-supertype as well, and also on a completely independent type. Then we can add these abstractions to std.typecons.
Jun 02 2010
On 6/2/10, Simen kjaeraas <simen.kjaras gmail.com> wrote: *snip* I haven't tried your code, but it looks similar to my own code, which had this problem: alias Typedef!Int Handle; alias Typedef!Int OtherHandle; void foo(Handle h) { } OtherHandle b; foo(b); // compiles, but shouldn't. Problem is that Handle and OtherHandle are both alias of the same underlying thing, so the compiler considers them the same thing! With the old typedef, I'm pretty sure it would (correctly IMO) complain here.
Jun 02 2010
On Wed, 02 Jun 2010 23:12:38 +0200, Adam Ruppe <destructionator gmail.com> wrote:On 6/2/10, Simen kjaeraas <simen.kjaras gmail.com> wrote: *snip* I haven't tried your code, but it looks similar to my own code, which had this problem: alias Typedef!Int Handle; alias Typedef!Int OtherHandle; void foo(Handle h) { } OtherHandle b; foo(b); // compiles, but shouldn't. Problem is that Handle and OtherHandle are both alias of the same underlying thing, so the compiler considers them the same thing! With the old typedef, I'm pretty sure it would (correctly IMO) complain here.My code sidesteps that by including instantiation line and file, making each instantiation unique (as long as you don't do multiple typedefs on one line). It is possible to sidestep this issue with a mixin template: mixin template typedef( string name, T ) { mixin(q{ struct } ~ name ~ q{ { //stuff } }); } But 'mixin Typedef!("myInt", int);' does not sit well with me. -- Simen
Jun 02 2010
Simen kjaeraas:My code sidesteps that by including instantiation line and file, making each instantiation unique (as long as you don't do multiple typedefs on one line).Cute :-) We can also try to add/invent something similar to the CLisp gensym, that generates ever different symbols at compile-time (just a letter plus an ever increasing integer number suffices). Bye, bearophile
Jun 02 2010
On Thu, 03 Jun 2010 00:02:03 +0200, Simen kjaeraas wrote:On Wed, 02 Jun 2010 23:12:38 +0200, Adam Ruppe <destructionator gmail.com> wrote:Cool trick! :) -LarsOn 6/2/10, Simen kjaeraas <simen.kjaras gmail.com> wrote: *snip* I haven't tried your code, but it looks similar to my own code, which had this problem: alias Typedef!Int Handle; alias Typedef!Int OtherHandle; void foo(Handle h) { } OtherHandle b; foo(b); // compiles, but shouldn't. Problem is that Handle and OtherHandle are both alias of the same underlying thing, so the compiler considers them the same thing! With the old typedef, I'm pretty sure it would (correctly IMO) complain here.My code sidesteps that by including instantiation line and file, making each instantiation unique (as long as you don't do multiple typedefs on one line).
Jun 02 2010
On 3-6-2010 14:58, Lars T. Kyllingstad wrote:On Thu, 03 Jun 2010 00:02:03 +0200, Simen kjaeraas wrote:Cool trick indeed, but why do we need a trick for something so basic!? A few years from now we'll wonder why compiling moderately sized D projects takes a long time. When you can do something, it doesn't mean that you should. L.On Wed, 02 Jun 2010 23:12:38 +0200, Adam Ruppe <destructionator gmail.com> wrote:Cool trick! :) -LarsOn 6/2/10, Simen kjaeraas <simen.kjaras gmail.com> wrote: *snip* I haven't tried your code, but it looks similar to my own code, which had this problem: alias Typedef!Int Handle; alias Typedef!Int OtherHandle; void foo(Handle h) { } OtherHandle b; foo(b); // compiles, but shouldn't. Problem is that Handle and OtherHandle are both alias of the same underlying thing, so the compiler considers them the same thing! With the old typedef, I'm pretty sure it would (correctly IMO) complain here.My code sidesteps that by including instantiation line and file, making each instantiation unique (as long as you don't do multiple typedefs on one line).
Jun 03 2010
My suggestion is to just improve the built-in typedef, instead of trying to implement some hack in D. Lionello Lunesu:Cool trick indeed, but why do we need a trick for something so basic!?For that a gensym is better than the date/file pair. But a gensym() despite being a simple thing might require compiler support to be implemented. Bye, bearophile
Jun 03 2010
On 6/3/10, bearophile <bearophileHUGS lycos.com> wrote:My suggestion is to just improve the built-in typedef, instead of trying to implement some hack in D.Do you consider ALL library solutions to be "hacks"? It sure seems that way at times. What we have here is individually useful language features able to completely replace another, specialized feature, and do even more! This strikes me as being a supremely elegant solution, not a hack. Fixing typedef ONLY fixes typedef, whereas fixing the helper components of Typedef can help a variety of things. If the helper templates are slow, improving template performance fixes that, and helps across the board!
Jun 03 2010
On 06/03/2010 12:17 PM, Adam Ruppe wrote:On 6/3/10, bearophile<bearophileHUGS lycos.com> wrote:Agreed. The reality was that typedef was in fact a hack; its semantics were quite erratic. A library-based solution can use the existing language to devise a principled artifact. AndreiMy suggestion is to just improve the built-in typedef, instead of trying to implement some hack in D.Do you consider ALL library solutions to be "hacks"? It sure seems that way at times. What we have here is individually useful language features able to completely replace another, specialized feature, and do even more! This strikes me as being a supremely elegant solution, not a hack. Fixing typedef ONLY fixes typedef, whereas fixing the helper components of Typedef can help a variety of things. If the helper templates are slow, improving template performance fixes that, and helps across the board!
Jun 03 2010
Adam Ruppe:Do you consider ALL library solutions to be "hacks"? It sure seems that way at times.I have seen some situations where library solutions are not good enough yet: - std.bitmanip.bitfields is a marvel of programming, but it's trash any way: its code can't be maintained, modified, read. It's past the limit of decency. And its syntax is not as good as C bitfields. - The best library "typedef" shown so far can't be used two times in the same line, it uses a line of code and file name as workaround, for me this is a hack. I have suggested a gensym() to improve the situation a bit, but even with it the syntax is not that good and it can produce some template bloat. - The TightArray so far is not good enough for its purposes. Probably it can be improved. - The suggested replacecement for scope seems to have a bit better semantics (it's an expression and maybe it doesn't suffer some of the implementation bugs of "scope" (see my bug report 4214)), but its syntax is borderline awful, so for now it is not an improvement over the current (buggy) situation. - All the proposed library implementations of array comprehensions that I have seen are bad (including the one I have used). Bye, bearophile
Jun 03 2010
On 6/3/10, bearophile <bearophileHUGS lycos.com> wrote:I have seen some situations where library solutions are not good enough yet: - std.bitmanip.bitfields is a marvel of programming, but it's trash any way: its code can't be maintained, modified, read. It's past the limit of decency.When it comes to code accessibility, the compiler is a black box. You can't edit it, even in theory, without breaking the language. A library's source might be ugly, but it is at least available for you to play with while still writing valid D code.And its syntax is not as good as C bitfields.It is very close though.- The best library "typedef" shown so far can't be used two times in the same line,Note: you can use it twice on one line under some circumstances still. But, be honest, have you ever actually put two typedefs on one line? If the limitation wasn't explained in the code, would you have ever noticed this? The only place where I can see it being an issue is if you use it inside a larger string mixin. The line numbers get really weird at times with them. But, it still seems like an academic problem.it uses a line of code and file name as workaround, for me this is a hack.When I saw the line/file arguments there, I assumed they were for debugging purposes - you can use them to make prettier error messages for the user. The benefit of letting the distinct types work is a cool side effect. I'll agree that it is a bit weird, but it does the job and isn't really evil.I have suggested a gensym() to improve the situation a bit, but even with it the syntax is not that good and it can produce some template bloat.I think a gensym would be useful. If CTFE could get to a static variable, that'd be cool. string getsym() { static int count = 0; count++; return "_AUTOMATICALLY_GENERATED_SYMBOL_" ~ to!string(count); } Then, mixin(getsym()) on the useage end. This doesn't work right now because the global isn't accessible at compile time....- The TightArray so far is not good enough for its purposes. Probably it can be improved.Yes.- The suggested replacecement for scope seems to have a bit better semantics (it's an expression and maybe it doesn't suffer some of the implementation bugs of "scope" (see my bug report 4214)), but its syntax is borderline awful, so for now it is not an improvement over the current (buggy) situation.The syntax should be easy to turn into: Scoped!Object obj; since it is basically just a wrapper struct. What I especially like about this situation is how it has potential to do a variety of things, like stack allocation, or malloc(), or just about anything else. I'd like to see the built in new moved to the library too, actually. auto a = new!Object(args...); should be possible even now!- All the proposed library implementations of array comprehensions that I have seen are bad (including the one I have used).I haven't used any so I can't say.
Jun 03 2010
Adam Ruppe:When it comes to code accessibility, the compiler is a black box. You can't edit it, even in theory, without breaking the language. A library's source might be ugly, but it is at least available for you to play with while still writing valid D code.Code that can be mantained inside the compiler is sometimes better than user code that can't be touched (I have tried to improve the error messages of those bitfields for about one hour and I have failed) :-)But, be honest, have you ever actually put two typedefs on one line?<I think I have never put two typedefs on one line, but hidden traps are bad.If CTFE could get to a static variable, that'd be cool.<Or the gensym can have compiler support ;-) If D3 will have some form of macros then a gensym will probably be even more useful. Bye, bearophile
Jun 03 2010
Thu, 03 Jun 2010 15:08:08 -0400, Adam Ruppe wrote:On 6/3/10, bearophile <bearophileHUGS lycos.com> wrote:Don't forget machine generated code. E.g. CTFE or parser generatorsI have seen some situations where library solutions are not good enough yet: - std.bitmanip.bitfields is a marvel of programming, but it's trash any way: its code can't be maintained, modified, read. It's past the limit of decency.When it comes to code accessibility, the compiler is a black box. You can't edit it, even in theory, without breaking the language. A library's source might be ugly, but it is at least available for you to play with while still writing valid D code.And its syntax is not as good as C bitfields.It is very close though.- The best library "typedef" shown so far can't be used two times in the same line,Note: you can use it twice on one line under some circumstances still. But, be honest, have you ever actually put two typedefs on one line? If the limitation wasn't explained in the code, would you have ever noticed this?
Jun 03 2010
On 4-6-2010 1:17, Adam Ruppe wrote:.... This strikes me as being a supremely elegant solution, not a hack.struct Typedef( T, T init = T.init, Type type = Type.Sub, string _f = __FILE__, int _l = __LINE__ ) { ... Yes, that's a hack. And it's great that we can do sub, super, independent and parallel, but the question is: are they needed? I thought I had found a compelling use case for typedef. Perhaps, instead of throwing it out because it was ill defined, we should define what's it supposed to solve and then make sure that's exactly what it does, and nothing more. L.
Jun 04 2010
On 06/04/2010 06:38 AM, Lionello Lunesu wrote:On 4-6-2010 1:17, Adam Ruppe wrote:The problem is, there's not only one good use. Walter and I identified at least a gew. The built-in typedef fails all examples below because it was very superficially designed. 1. Something that's just like another type yet "parallel" with it. This is good for abstractions that encode different units of measurement that aren't supposed to be mixed. ParallelTypedef!double Miles; Such a type should accept explicit initialization from a regular double: auto dist = Miles(3.2); However it shouldn't accept initialization from another parallel typedef: ParallelTypedef!double Kms; auto dist1 = Kms(4); auto dist2 = Miles(dist1); // no Arithmetic operations should only work within Miles but not mixing Miles with other types. Here's where things already get complicated - you do want to allow some operations between Miles and double (e.g. "*"), in some others you don't (e.g. "+"). Here's where a library facility would help: ParallelTypdef!(double, "allow_arithmetic", "allow_mixed:*,/,%") Miles; 2. Opaque "handle" types that can be used with overloading. The base type of the typedef is just the storage strategy: OpaqueTypedef!int FileHandle; Such a typedef supports no arithmetic and no implicit conversions. You can explicitly initialize it from an int and you can cast it back to it using an explicit cast. 3. Proper subtype. Create a true subtype of a type that allows explicit initialization from the type and implicit conversion to the type. SubtypeTypedef!Exception MyException; 4. Proper supertype. The base type implicitly converts to the introduced type, but not vice versa. SupertypeTypedef!uint Bits; Andrei.... This strikes me as being a supremely elegant solution, not a hack.struct Typedef( T, T init = T.init, Type type = Type.Sub, string _f = __FILE__, int _l = __LINE__ ) { ... Yes, that's a hack. And it's great that we can do sub, super, independent and parallel, but the question is: are they needed? I thought I had found a compelling use case for typedef. Perhaps, instead of throwing it out because it was ill defined, we should define what's it supposed to solve and then make sure that's exactly what it does, and nothing more.
Jun 04 2010
struct Typedef( T ) { T payload; alias payload this; } alias Typedef!int myInt; There you go.The question is if this still works flawlessly for complicated examples.
May 31 2010
On Tue, 01 Jun 2010 05:07:21 +0200, Simen kjaeraas wrote:Lionello Lunesu <lio lunesu.remove.com> wrote:Nice. :) But it isn't quite a typedef, because if you do alias Typedef!int myInt; alias Typedef!int yourInt; then myInt and yourInt will refer to the same type. How about this instead: mixin template Typedef(T, string name) { mixin("struct "~name~" { T payload; alias payload this; }"); } Then, mixin Typedef!(int, "myInt"); mixin Typedef!(int, "yourInt"); will define two distinct types. If we had Andrei's (or was it Walter's?) "new alias" feature it would be even cooler: mixin template Typedef(T, new alias name) { struct name { T payload; alias payload this; } } mixin Typedef!(int, myInt); mixin Typedef!(int, yourInt); :) -LarsI also miss typedef. I thought D had a great opportunity to fix it. Take something like the Windows headers. It mostly consists of typedefs for handles and whatnot. Without typedef you'd have to use alias and type safety is out of the windows. So what would be the way to translate those Windows headers? Create a unique struct for each old typedef? With alias this, and a ctor? Well, if that's the way to do it now, why not make typedef a shortcut for exactly that!? IIRC typedef is gone because you and Walter could not agree whether it had to be a subtype or a supertype of the typedef'ed type. For me it's rather simple: I want to introduce a new type in such a way that it helps me prevent mistakes, ie. passing one handle when the function wants another, even though both are based on void*, or whatever. Bring typedef back!struct Typedef( T ) { T payload; alias payload this; } alias Typedef!int myInt; There you go.
Jun 01 2010
On 05/31/2010 03:54 PM, bearophile wrote:Andrei Alexandrescu:user specified T.init?typedef is gone.*mewls* I have shown here some examples of typedef usage, and I'll keep posting few more in future. I'd like to pull it back from the grave and keep it :-) Bye, bearophile
May 31 2010
On 1-6-2010 6:25, Ellery Newcomer wrote:user specified T.init?I love(d) that feature!
May 31 2010
Andrei Alexandrescu wrote:On 05/31/2010 02:14 PM, bearophile wrote:struct initializers are gone too?Trass3r:typedef is gone. AndreiNobody got an answer?My opinion: - complex types will be removed. And as far as I know complex number literals too will be removed from D (this is less nice). - I am not sure regarding C-style struct initializations. They are useful to save some typing if you have to for example to put a long array of struct literals in your source code. I presume they will be removed. - Typedef has some limitations, but I think it will be kept because it is useful.
Jun 06 2010
On 06/06/2010 10:23 AM, Lutger wrote:Andrei Alexandrescu wrote:You mean { }? I seem to remember Walter mentioned they are no longer relevant. AndreiOn 05/31/2010 02:14 PM, bearophile wrote:struct initializers are gone too?Trass3r:typedef is gone. AndreiNobody got an answer?My opinion: - complex types will be removed. And as far as I know complex number literals too will be removed from D (this is less nice). - I am not sure regarding C-style struct initializations. They are useful to save some typing if you have to for example to put a long array of struct literals in your source code. I presume they will be removed. - Typedef has some limitations, but I think it will be kept because it is useful.
Jun 06 2010
On 06/06/2010 10:40 AM, Andrei Alexandrescu wrote:On 06/06/2010 10:23 AM, Lutger wrote:Ooo Ooo Ooo Can we get rid of them? Pretty pretty please?Andrei Alexandrescu wrote:You mean { }? I seem to remember Walter mentioned they are no longer relevant. AndreiOn 05/31/2010 02:14 PM, bearophile wrote:struct initializers are gone too?Trass3r:typedef is gone. AndreiNobody got an answer?My opinion: - complex types will be removed. And as far as I know complex number literals too will be removed from D (this is less nice). - I am not sure regarding C-style struct initializations. They are useful to save some typing if you have to for example to put a long array of struct literals in your source code. I presume they will be removed. - Typedef has some limitations, but I think it will be kept because it is useful.
Jun 06 2010
Ellery Newcomer:Ooo Ooo Ooo Can we get rid of them? Pretty pretty please?Why are you so eager to remove them? (They are not essential, D has plenty of other ways (maybe even too many) to instantiate a struct. But I have appreciated C-style struct initializers in D because they give a more compact syntax when I have to define many small structs inside an array literal). Bye, bearophile
Jun 06 2010
On 06/06/2010 10:47 AM, bearophile wrote:Ellery Newcomer:because they're difficult to disambiguate from function literals (at least dmd doesn't do it correctly) because they entail a lot of lookahead (I don't know, but I suspect they are the cause for most of the slowness in my parser) because they're the only reason we have ArrayInitializer and without them we could merge it with ArrayLiteral I won't disagree that it's a nice syntax, though.Ooo Ooo Ooo Can we get rid of them? Pretty pretty please?Why are you so eager to remove them? (They are not essential, D has plenty of other ways (maybe even too many) to instantiate a struct. But I have appreciated C-style struct initializers in D because they give a more compact syntax when I have to define many small structs inside an array literal). Bye, bearophile
Jun 06 2010