digitalmars.D - struct inheritance
- Bill Baxter (20/20) Aug 30 2007 Let us all turn our copies of WalterAndrei.pdf to page 40 where yea
- Robert Fraser (5/31) Aug 30 2007 It amounts to the same thing, so it just depends on which syntax you pre...
- Bill Baxter (18/54) Aug 30 2007 I did just think of one issue which is that constructors/opCalls for M
- kris (15/79) Aug 30 2007 Perhaps a bigger problem is this:
- Bill Baxter (13/100) Aug 30 2007 Well for the 'import' syntax it wouldn't be so bad. The compiler could
- Reiner Pope (23/54) Aug 30 2007 I'm not sure why imported members do have to appear first. Is there a
- Regan Heath (17/102) Aug 31 2007 When you say "derived from M" are you referring to the ordering/layout
- kris (8/117) Aug 31 2007 Briefy:
- Regan Heath (6/127) Aug 31 2007 Yep, exactly. In this case you definately want S to extend M and in
- kris (11/29) Aug 31 2007 If you're not interested in 'extending' per se, but prefer composition,
- Bill Baxter (14/113) Aug 31 2007 Another good use for structs is for traits class with little or no data....
- kris (4/121) Aug 31 2007 Another principal use it to enclose an opApply() with some relevant
-
Don Clugston
(2/125)
Sep 03 2007
Looking forward to your next talk "foreach fo' Shizzle".
- kris (3/9) Sep 03 2007 heh ... should perhaps try "Yo Mama!" for that one :)
- Regan Heath (4/119) Sep 03 2007 The proposed struct inheritance only inherits fields, not
- BCS (2/15) Sep 03 2007
- kris (5/31) Aug 30 2007 Perhaps because the alias itself is optional? It just brings the members...
- Reiner Pope (4/30) Aug 30 2007 Template mixins require that the sourcecode of the template is available...
- Don Clugston (3/36) Aug 30 2007 Also, Walter wants to get of template mixins. (That was discussed a litt...
- BCS (6/9) Aug 30 2007 WHAT!! They are such a wonderful solution to a number of interesting pro...
- Don Clugston (2/15) Sep 01 2007
- Bill Baxter (8/43) Aug 31 2007 Just to be clear -- I'm not saying the 'mixin M' should be a shortcut
- Jari-Matti =?ISO-8859-1?Q?M=E4kel=E4?= (16/60) Aug 31 2007 Sounds really hilarious since I've always considered mixins to be macros...
- kris (3/5) Aug 31 2007 Hoorah! Hoorah!
- Bruno Medeiros (14/47) Sep 01 2007 Huh? Explain how the above alias example would work if the compiler
- Reiner Pope (5/53) Sep 01 2007 All you need is a declaration of M's interface, you don't need to
- Bruno Medeiros (18/73) Sep 01 2007 You mean like ?
- Bruno Medeiros (10/86) Sep 01 2007 Hum, that being the case, then yes it's different, mostly due to the
Let us all turn our copies of WalterAndrei.pdf to page 40 where yea verily it doth say: struct M { int a; } struct S { M m; alias m this; int b; } Why not just allow mixin to do this? struct M { int a; } struct S { mixin M; int b; } That's basically the way it's done now except now it would be more like: template MMixin() { int a; } struct M { mixin M; } struct S { mixin M; int b; } Just let us treat a struct like a zero arg template for mixin purposes. --bb
Aug 30 2007
Bill Baxter Wrote:Let us all turn our copies of WalterAndrei.pdf to page 40 where yea verily it doth say: struct M { int a; } struct S { M m; alias m this; int b; } Why not just allow mixin to do this? struct M { int a; } struct S { mixin M; int b; } That's basically the way it's done now except now it would be more like: template MMixin() { int a; } struct M { mixin M; } struct S { mixin M; int b; } Just let us treat a struct like a zero arg template for mixin purposes. --bbIt amounts to the same thing, so it just depends on which syntax you prefer. Personally, I like... struct S : M { int b; } ... meaning S is non-polymorphically inherited from M. I guess the argument against taht syntax was that it would be confusing for people from a C++ background who assume polymorphic inheritance for structs. Anyways, it's up to Walter to decide on the syntax, and he says "alias this".
Aug 30 2007
Robert Fraser wrote:Bill Baxter Wrote:I did just think of one issue which is that constructors/opCalls for M would be weird. S needs to decide how to initialize the M part, which would be difficult if M's constructors are just mixed in directly. I guess from a compiler-writers perspective "alias this" is more like what actually happens when you inherit in typical C++ fashion. In that case I guess I'd prefer 'import' struct M { int a; } struct S { import M; int b; } then you can specify when you need to access the M parts just like you do in C++ by M.member. I'd even prefer "alias m .;" to "alias m this;". It just seems wrong and goes against the nice happy view that 'this' is just an implicitly defined pointer member. --bbLet us all turn our copies of WalterAndrei.pdf to page 40 where yea verily it doth say: struct M { int a; } struct S { M m; alias m this; int b; } Why not just allow mixin to do this? struct M { int a; } struct S { mixin M; int b; } That's basically the way it's done now except now it would be more like: template MMixin() { int a; } struct M { mixin M; } struct S { mixin M; int b; } Just let us treat a struct like a zero arg template for mixin purposes. --bbIt amounts to the same thing, so it just depends on which syntax you prefer. Personally, I like... struct S : M { int b; } ... meaning S is non-polymorphically inherited from M. I guess the argument against taht syntax was that it would be confusing for people from a C++ background who assume polymorphic inheritance for structs. Anyways, it's up to Walter to decide on the syntax, and he says "alias this".
Aug 30 2007
Bill Baxter wrote:Robert Fraser wrote:Perhaps a bigger problem is this: Now, S is no longer derived from M. Hence, it would seem the right way to do this is to take it out of the hands of the developer and do something akin to as had been suggested previously. Sure, that particular syntax may mean something else to some C++ folks, but at least the intent is clear and the /outcome/ is consistent. BTW, did you select S&M for a specific reason? :pBill Baxter Wrote:I did just think of one issue which is that constructors/opCalls for M would be weird. S needs to decide how to initialize the M part, which would be difficult if M's constructors are just mixed in directly. I guess from a compiler-writers perspective "alias this" is more like what actually happens when you inherit in typical C++ fashion. In that case I guess I'd prefer 'import' struct M { int a; } struct S { import M; int b; } then you can specify when you need to access the M parts just like you do in C++ by M.member. I'd even prefer "alias m .;" to "alias m this;". It just seems wrong and goes against the nice happy view that 'this' is just an implicitly defined pointer member. --bbLet us all turn our copies of WalterAndrei.pdf to page 40 where yea verily it doth say: struct M { int a; } struct S { M m; alias m this; int b; } Why not just allow mixin to do this? struct M { int a; } struct S { mixin M; int b; } That's basically the way it's done now except now it would be more like: template MMixin() { int a; } struct M { mixin M; } struct S { mixin M; int b; } Just let us treat a struct like a zero arg template for mixin purposes. --bbIt amounts to the same thing, so it just depends on which syntax you prefer. Personally, I like... struct S : M { int b; } ... meaning S is non-polymorphically inherited from M. I guess the argument against taht syntax was that it would be confusing for people from a C++ background who assume polymorphic inheritance for structs. Anyways, it's up to Walter to decide on the syntax, and he says "alias this".
Aug 30 2007
kris wrote:Bill Baxter wrote:Well for the 'import' syntax it wouldn't be so bad. The compiler could just say "imported members will always appear first". With the alias syntax that would be a bit weirder since there's already an "M m" right there in the struct (which I assume you would still be able to access via the .m). Since there's a visible member there, it makes less sense for the compiler to move the fields around.Robert Fraser wrote:Perhaps a bigger problem is this: Now, S is no longer derived from M.Bill Baxter Wrote:I did just think of one issue which is that constructors/opCalls for M would be weird. S needs to decide how to initialize the M part, which would be difficult if M's constructors are just mixed in directly. I guess from a compiler-writers perspective "alias this" is more like what actually happens when you inherit in typical C++ fashion. In that case I guess I'd prefer 'import' struct M { int a; } struct S { import M; int b; } then you can specify when you need to access the M parts just like you do in C++ by M.member. I'd even prefer "alias m .;" to "alias m this;". It just seems wrong and goes against the nice happy view that 'this' is just an implicitly defined pointer member. --bbLet us all turn our copies of WalterAndrei.pdf to page 40 where yea verily it doth say: struct M { int a; } struct S { M m; alias m this; int b; } Why not just allow mixin to do this? struct M { int a; } struct S { mixin M; int b; } That's basically the way it's done now except now it would be more like: template MMixin() { int a; } struct M { mixin M; } struct S { mixin M; int b; } Just let us treat a struct like a zero arg template for mixin purposes. --bbIt amounts to the same thing, so it just depends on which syntax you prefer. Personally, I like... struct S : M { int b; } ... meaning S is non-polymorphically inherited from M. I guess the argument against taht syntax was that it would be confusing for people from a C++ background who assume polymorphic inheritance for structs. Anyways, it's up to Walter to decide on the syntax, and he says "alias this".Hence, it would seem the right way to do this is to take it out of the hands of the developer and do something akin to as had been suggested previously. Sure, that particular syntax may mean something else to some C++ folks, but at least the intent is clear and the /outcome/ is consistent.Yeh. I agree. I think that syntax would be better too. I was just assuming that *not* using that syntax was something that we wouldn't change Walter's mind about. But maybe there's hope.BTW, did you select S&M for a specific reason? :pYou'll have to ask Walter about that :-) It's right from their presentation. --bb
Aug 30 2007
Bill Baxter wrote:kris wrote:I'm not sure why imported members do have to appear first. Is there a reason that S is derived from M only if M is the first member of S? In lieu of a vtbl, S being derived from M presumably only means that S can be implicitly converted to M. So what's wrong with writing struct M { int a; } struct S { int b; M m; alias m this; M opImplicitCastTo() { return m; } }Perhaps a bigger problem is this: Now, S is no longer derived from M.Well for the 'import' syntax it wouldn't be so bad. The compiler could just say "imported members will always appear first". With the alias syntax that would be a bit weirder since there's already an "M m" right there in the struct (which I assume you would still be able to access via the .m). Since there's a visible member there, it makes less sense for the compiler to move the fields around.I think that "alias this" may become more interesting when aliases work with any expression. You could write things like struct S { M m; alias m.a this; } You can't really express this neatly with inheritance (in my opinion). Of course, the import syntax works just as well, but I think alias expresses exactly what you're doing, and doesn't require introduction of a distinct concept to the language. -- ReinerHence, it would seem the right way to do this is to take it out of the hands of the developer and do something akin to as had been suggested previously. Sure, that particular syntax may mean something else to some C++ folks, but at least the intent is clear and the /outcome/ is consistent.Yeh. I agree. I think that syntax would be better too. I was just assuming that *not* using that syntax was something that we wouldn't change Walter's mind about. But maybe there's hope.
Aug 30 2007
kris wrote:Bill Baxter wrote:When you say "derived from M" are you referring to the ordering/layout of M matching that of the start of S (new fields of S therefore existing in the part of S which is larger than M). I'm not sure "derived" is the right term to use, we don't want to confuse it with class derivation, perhaps saying "S is based on M" is better? /You say potatoes I say ../ As one of the main reasons/uses for structs is to define a specific layout in memory, perhaps the main reason for Walters syntax is to make it possible to define that layout however required. I think there are cases where they should match, and you should be able to cast from S to M (albeit with slicing and woe to the developer who tries to cast an array of S to M - but perhaps the cast operator can handle this case?). In this case S is based on M. I think there are also cases where you need to specify a different layout and in this case S would not be based on M. ReganRobert Fraser wrote:Perhaps a bigger problem is this: Now, S is no longer derived from M. Hence, it would seem the right way to do this is to take it out of the hands of the developer and do something akin to as had been suggested previously. Sure, that particular syntax may mean something else to some C++ folks, but at least the intent is clear and the /outcome/ is consistent.Bill Baxter Wrote:I did just think of one issue which is that constructors/opCalls for M would be weird. S needs to decide how to initialize the M part, which would be difficult if M's constructors are just mixed in directly. I guess from a compiler-writers perspective "alias this" is more like what actually happens when you inherit in typical C++ fashion. In that case I guess I'd prefer 'import' struct M { int a; } struct S { import M; int b; } then you can specify when you need to access the M parts just like you do in C++ by M.member. I'd even prefer "alias m .;" to "alias m this;". It just seems wrong and goes against the nice happy view that 'this' is just an implicitly defined pointer member. --bbLet us all turn our copies of WalterAndrei.pdf to page 40 where yea verily it doth say: struct M { int a; } struct S { M m; alias m this; int b; } Why not just allow mixin to do this? struct M { int a; } struct S { mixin M; int b; } That's basically the way it's done now except now it would be more like: template MMixin() { int a; } struct M { mixin M; } struct S { mixin M; int b; } Just let us treat a struct like a zero arg template for mixin purposes. --bbIt amounts to the same thing, so it just depends on which syntax you prefer. Personally, I like... struct S : M { int b; } ... meaning S is non-polymorphically inherited from M. I guess the argument against taht syntax was that it would be confusing for people from a C++ background who assume polymorphic inheritance for structs. Anyways, it's up to Walter to decide on the syntax, and he says "alias this".
Aug 31 2007
Regan Heath wrote:kris wrote:Briefy: ok, S /extends/ M :) The ordering becomes an issue when you have a pointer to S, and wish to use it as a pointer to an M. That's why, in C, the super-struct is manually inserted as the first struct member. If you manually insert the super-struct as the second or third member then, obviously, your pointer is not convertibleBill Baxter wrote:When you say "derived from M" are you referring to the ordering/layout of M matching that of the start of S (new fields of S therefore existing in the part of S which is larger than M). I'm not sure "derived" is the right term to use, we don't want to confuse it with class derivation, perhaps saying "S is based on M" is better? /You say potatoes I say ../ As one of the main reasons/uses for structs is to define a specific layout in memory, perhaps the main reason for Walters syntax is to make it possible to define that layout however required. I think there are cases where they should match, and you should be able to cast from S to M (albeit with slicing and woe to the developer who tries to cast an array of S to M - but perhaps the cast operator can handle this case?). In this case S is based on M. I think there are also cases where you need to specify a different layout and in this case S would not be based on M. ReganRobert Fraser wrote:Perhaps a bigger problem is this: Now, S is no longer derived from M. Hence, it would seem the right way to do this is to take it out of the hands of the developer and do something akin to as had been suggested previously. Sure, that particular syntax may mean something else to some C++ folks, but at least the intent is clear and the /outcome/ is consistent.Bill Baxter Wrote:I did just think of one issue which is that constructors/opCalls for M would be weird. S needs to decide how to initialize the M part, which would be difficult if M's constructors are just mixed in directly. I guess from a compiler-writers perspective "alias this" is more like what actually happens when you inherit in typical C++ fashion. In that case I guess I'd prefer 'import' struct M { int a; } struct S { import M; int b; } then you can specify when you need to access the M parts just like you do in C++ by M.member. I'd even prefer "alias m .;" to "alias m this;". It just seems wrong and goes against the nice happy view that 'this' is just an implicitly defined pointer member. --bbLet us all turn our copies of WalterAndrei.pdf to page 40 where yea verily it doth say: struct M { int a; } struct S { M m; alias m this; int b; } Why not just allow mixin to do this? struct M { int a; } struct S { mixin M; int b; } That's basically the way it's done now except now it would be more like: template MMixin() { int a; } struct M { mixin M; } struct S { mixin M; int b; } Just let us treat a struct like a zero arg template for mixin purposes. --bbIt amounts to the same thing, so it just depends on which syntax you prefer. Personally, I like... struct S : M { int b; } ... meaning S is non-polymorphically inherited from M. I guess the argument against taht syntax was that it would be confusing for people from a C++ background who assume polymorphic inheritance for structs. Anyways, it's up to Walter to decide on the syntax, and he says "alias this".
Aug 31 2007
kris wrote:Regan Heath wrote:<g>kris wrote:Briefy: ok, S /extends/ M :)Bill Baxter wrote:When you say "derived from M" are you referring to the ordering/layout of M matching that of the start of S (new fields of S therefore existing in the part of S which is larger than M). I'm not sure "derived" is the right term to use, we don't want to confuse it with class derivation, perhaps saying "S is based on M" is better? /You say potatoes I say ../ As one of the main reasons/uses for structs is to define a specific layout in memory, perhaps the main reason for Walters syntax is to make it possible to define that layout however required. I think there are cases where they should match, and you should be able to cast from S to M (albeit with slicing and woe to the developer who tries to cast an array of S to M - but perhaps the cast operator can handle this case?). In this case S is based on M. I think there are also cases where you need to specify a different layout and in this case S would not be based on M. ReganRobert Fraser wrote:Perhaps a bigger problem is this: Now, S is no longer derived from M. Hence, it would seem the right way to do this is to take it out of the hands of the developer and do something akin to as had been suggested previously. Sure, that particular syntax may mean something else to some C++ folks, but at least the intent is clear and the /outcome/ is consistent.Bill Baxter Wrote:I did just think of one issue which is that constructors/opCalls for M would be weird. S needs to decide how to initialize the M part, which would be difficult if M's constructors are just mixed in directly. I guess from a compiler-writers perspective "alias this" is more like what actually happens when you inherit in typical C++ fashion. In that case I guess I'd prefer 'import' struct M { int a; } struct S { import M; int b; } then you can specify when you need to access the M parts just like you do in C++ by M.member. I'd even prefer "alias m .;" to "alias m this;". It just seems wrong and goes against the nice happy view that 'this' is just an implicitly defined pointer member. --bbLet us all turn our copies of WalterAndrei.pdf to page 40 where yea verily it doth say: struct M { int a; } struct S { M m; alias m this; int b; } Why not just allow mixin to do this? struct M { int a; } struct S { mixin M; int b; } That's basically the way it's done now except now it would be more like: template MMixin() { int a; } struct M { mixin M; } struct S { mixin M; int b; } Just let us treat a struct like a zero arg template for mixin purposes. --bbIt amounts to the same thing, so it just depends on which syntax you prefer. Personally, I like... struct S : M { int b; } ... meaning S is non-polymorphically inherited from M. I guess the argument against taht syntax was that it would be confusing for people from a C++ background who assume polymorphic inheritance for structs. Anyways, it's up to Walter to decide on the syntax, and he says "alias this".The ordering becomes an issue when you have a pointer to S, and wish to use it as a pointer to an M. That's why, in C, the super-struct is manually inserted as the first struct member. If you manually insert the super-struct as the second or third member then, obviously, your pointer is not convertibleYep, exactly. In this case you definately want S to extend M and in this exact manner. However, I wonder if there are cases where you want a different layout in memory. If so, the syntax must support both options. Regan
Aug 31 2007
Regan Heath wrote:kris wrote:[snip]If you're not interested in 'extending' per se, but prefer composition, then one will always be able to do this: struct S { int foo, bar; M m; OtherStruct other; char[] wumpus; }Briefy: ok, S /extends/ M :)<g>The ordering becomes an issue when you have a pointer to S, and wish to use it as a pointer to an M. That's why, in C, the super-struct is manually inserted as the first struct member. If you manually insert the super-struct as the second or third member then, obviously, your pointer is not convertibleYep, exactly. In this case you definately want S to extend M and in this exact manner. However, I wonder if there are cases where you want a different layout in memory. If so, the syntax must support both options. Regan
Aug 31 2007
Regan Heath wrote:kris wrote:Another good use for structs is for traits class with little or no data. Mostly just a collection of types and static functions. Having the ability to extend these structs is handy. A library can define a set of base types A, and users can add to or modify it without having to know all the stuff that was in A to begin with. Or vice versa, I define the base and pass that to the library and the library adds a few more things to it. The reason these should be structs is because sometimes you want to add in maybe one or two small data members that control operation. For instance you might have a 'compare' function in the traits and want to parameterize it by a data member to act like either less-than or greater-than. Such things should have value semantics. --bbBill Baxter wrote:When you say "derived from M" are you referring to the ordering/layout of M matching that of the start of S (new fields of S therefore existing in the part of S which is larger than M). I'm not sure "derived" is the right term to use, we don't want to confuse it with class derivation, perhaps saying "S is based on M" is better? /You say potatoes I say ../ As one of the main reasons/uses for structs is to define a specific layout in memory, perhaps the main reason for Walters syntax is to make it possible to define that layout however required.Robert Fraser wrote:Perhaps a bigger problem is this: Now, S is no longer derived from M. Hence, it would seem the right way to do this is to take it out of the hands of the developer and do something akin to as had been suggested previously. Sure, that particular syntax may mean something else to some C++ folks, but at least the intent is clear and the /outcome/ is consistent.Bill Baxter Wrote:I did just think of one issue which is that constructors/opCalls for M would be weird. S needs to decide how to initialize the M part, which would be difficult if M's constructors are just mixed in directly. I guess from a compiler-writers perspective "alias this" is more like what actually happens when you inherit in typical C++ fashion. In that case I guess I'd prefer 'import' struct M { int a; } struct S { import M; int b; } then you can specify when you need to access the M parts just like you do in C++ by M.member. I'd even prefer "alias m .;" to "alias m this;". It just seems wrong and goes against the nice happy view that 'this' is just an implicitly defined pointer member. --bbLet us all turn our copies of WalterAndrei.pdf to page 40 where yea verily it doth say: struct M { int a; } struct S { M m; alias m this; int b; } Why not just allow mixin to do this? struct M { int a; } struct S { mixin M; int b; } That's basically the way it's done now except now it would be more like: template MMixin() { int a; } struct M { mixin M; } struct S { mixin M; int b; } Just let us treat a struct like a zero arg template for mixin purposes. --bbIt amounts to the same thing, so it just depends on which syntax you prefer. Personally, I like... struct S : M { int b; } ... meaning S is non-polymorphically inherited from M. I guess the argument against taht syntax was that it would be confusing for people from a C++ background who assume polymorphic inheritance for structs. Anyways, it's up to Walter to decide on the syntax, and he says "alias this".
Aug 31 2007
Bill Baxter wrote:Regan Heath wrote:Another principal use it to enclose an opApply() with some relevant context. Returning such things by value to a foreach() is one of the coolest things about Dkris wrote:Another good use for structs is for traits class with little or no data. Mostly just a collection of types and static functions. Having the ability to extend these structs is handy. A library can define a set of base types A, and users can add to or modify it without having to know all the stuff that was in A to begin with. Or vice versa, I define the base and pass that to the library and the library adds a few more things to it. The reason these should be structs is because sometimes you want to add in maybe one or two small data members that control operation. For instance you might have a 'compare' function in the traits and want to parameterize it by a data member to act like either less-than or greater-than. Such things should have value semantics. --bbBill Baxter wrote:When you say "derived from M" are you referring to the ordering/layout of M matching that of the start of S (new fields of S therefore existing in the part of S which is larger than M). I'm not sure "derived" is the right term to use, we don't want to confuse it with class derivation, perhaps saying "S is based on M" is better? /You say potatoes I say ../ As one of the main reasons/uses for structs is to define a specific layout in memory, perhaps the main reason for Walters syntax is to make it possible to define that layout however required.Robert Fraser wrote:Perhaps a bigger problem is this: Now, S is no longer derived from M. Hence, it would seem the right way to do this is to take it out of the hands of the developer and do something akin to as had been suggested previously. Sure, that particular syntax may mean something else to some C++ folks, but at least the intent is clear and the /outcome/ is consistent.Bill Baxter Wrote:I did just think of one issue which is that constructors/opCalls for M would be weird. S needs to decide how to initialize the M part, which would be difficult if M's constructors are just mixed in directly. I guess from a compiler-writers perspective "alias this" is more like what actually happens when you inherit in typical C++ fashion. In that case I guess I'd prefer 'import' struct M { int a; } struct S { import M; int b; } then you can specify when you need to access the M parts just like you do in C++ by M.member. I'd even prefer "alias m .;" to "alias m this;". It just seems wrong and goes against the nice happy view that 'this' is just an implicitly defined pointer member. --bbLet us all turn our copies of WalterAndrei.pdf to page 40 where yea verily it doth say: struct M { int a; } struct S { M m; alias m this; int b; } Why not just allow mixin to do this? struct M { int a; } struct S { mixin M; int b; } That's basically the way it's done now except now it would be more like: template MMixin() { int a; } struct M { mixin M; } struct S { mixin M; int b; } Just let us treat a struct like a zero arg template for mixin purposes. --bbIt amounts to the same thing, so it just depends on which syntax you prefer. Personally, I like... struct S : M { int b; } ... meaning S is non-polymorphically inherited from M. I guess the argument against taht syntax was that it would be confusing for people from a C++ background who assume polymorphic inheritance for structs. Anyways, it's up to Walter to decide on the syntax, and he says "alias this".
Aug 31 2007
kris wrote:Bill Baxter wrote:Looking forward to your next talk "foreach fo' Shizzle". <g>Regan Heath wrote:Another principal use it to enclose an opApply() with some relevant context. Returning such things by value to a foreach() is one of the coolest things about Dkris wrote:Another good use for structs is for traits class with little or no data. Mostly just a collection of types and static functions. Having the ability to extend these structs is handy. A library can define a set of base types A, and users can add to or modify it without having to know all the stuff that was in A to begin with. Or vice versa, I define the base and pass that to the library and the library adds a few more things to it. The reason these should be structs is because sometimes you want to add in maybe one or two small data members that control operation. For instance you might have a 'compare' function in the traits and want to parameterize it by a data member to act like either less-than or greater-than. Such things should have value semantics. --bbBill Baxter wrote:When you say "derived from M" are you referring to the ordering/layout of M matching that of the start of S (new fields of S therefore existing in the part of S which is larger than M). I'm not sure "derived" is the right term to use, we don't want to confuse it with class derivation, perhaps saying "S is based on M" is better? /You say potatoes I say ../ As one of the main reasons/uses for structs is to define a specific layout in memory, perhaps the main reason for Walters syntax is to make it possible to define that layout however required.Robert Fraser wrote:Perhaps a bigger problem is this: Now, S is no longer derived from M. Hence, it would seem the right way to do this is to take it out of the hands of the developer and do something akin to as had been suggested previously. Sure, that particular syntax may mean something else to some C++ folks, but at least the intent is clear and the /outcome/ is consistent.Bill Baxter Wrote:I did just think of one issue which is that constructors/opCalls for M would be weird. S needs to decide how to initialize the M part, which would be difficult if M's constructors are just mixed in directly. I guess from a compiler-writers perspective "alias this" is more like what actually happens when you inherit in typical C++ fashion. In that case I guess I'd prefer 'import' struct M { int a; } struct S { import M; int b; } then you can specify when you need to access the M parts just like you do in C++ by M.member. I'd even prefer "alias m .;" to "alias m this;". It just seems wrong and goes against the nice happy view that 'this' is just an implicitly defined pointer member. --bbLet us all turn our copies of WalterAndrei.pdf to page 40 where yea verily it doth say: struct M { int a; } struct S { M m; alias m this; int b; } Why not just allow mixin to do this? struct M { int a; } struct S { mixin M; int b; } That's basically the way it's done now except now it would be more like: template MMixin() { int a; } struct M { mixin M; } struct S { mixin M; int b; } Just let us treat a struct like a zero arg template for mixin purposes. --bbIt amounts to the same thing, so it just depends on which syntax you prefer. Personally, I like... struct S : M { int b; } ... meaning S is non-polymorphically inherited from M. I guess the argument against taht syntax was that it would be confusing for people from a C++ background who assume polymorphic inheritance for structs. Anyways, it's up to Walter to decide on the syntax, and he says "alias this".
Sep 03 2007
Don Clugston wrote:kris wrote:[snip]heh ... should perhaps try "Yo Mama!" for that one :)Another principal use it to enclose an opApply() with some relevant context. Returning such things by value to a foreach() is one of the coolest things about DLooking forward to your next talk "foreach fo' Shizzle". <g>
Sep 03 2007
Bill Baxter wrote:Regan Heath wrote:The proposed struct inheritance only inherits fields, not methods/functions though, right? Regankris wrote:Another good use for structs is for traits class with little or no data. Mostly just a collection of types and static functions. Having the ability to extend these structs is handy. A library can define a set of base types A, and users can add to or modify it without having to know all the stuff that was in A to begin with. Or vice versa, I define the base and pass that to the library and the library adds a few more things to it. The reason these should be structs is because sometimes you want to add in maybe one or two small data members that control operation. For instance you might have a 'compare' function in the traits and want to parameterize it by a data member to act like either less-than or greater-than. Such things should have value semantics.Bill Baxter wrote:When you say "derived from M" are you referring to the ordering/layout of M matching that of the start of S (new fields of S therefore existing in the part of S which is larger than M). I'm not sure "derived" is the right term to use, we don't want to confuse it with class derivation, perhaps saying "S is based on M" is better? /You say potatoes I say ../ As one of the main reasons/uses for structs is to define a specific layout in memory, perhaps the main reason for Walters syntax is to make it possible to define that layout however required.Robert Fraser wrote:Perhaps a bigger problem is this: Now, S is no longer derived from M. Hence, it would seem the right way to do this is to take it out of the hands of the developer and do something akin to as had been suggested previously. Sure, that particular syntax may mean something else to some C++ folks, but at least the intent is clear and the /outcome/ is consistent.Bill Baxter Wrote:I did just think of one issue which is that constructors/opCalls for M would be weird. S needs to decide how to initialize the M part, which would be difficult if M's constructors are just mixed in directly. I guess from a compiler-writers perspective "alias this" is more like what actually happens when you inherit in typical C++ fashion. In that case I guess I'd prefer 'import' struct M { int a; } struct S { import M; int b; } then you can specify when you need to access the M parts just like you do in C++ by M.member. I'd even prefer "alias m .;" to "alias m this;". It just seems wrong and goes against the nice happy view that 'this' is just an implicitly defined pointer member. --bbLet us all turn our copies of WalterAndrei.pdf to page 40 where yea verily it doth say: struct M { int a; } struct S { M m; alias m this; int b; } Why not just allow mixin to do this? struct M { int a; } struct S { mixin M; int b; } That's basically the way it's done now except now it would be more like: template MMixin() { int a; } struct M { mixin M; } struct S { mixin M; int b; } Just let us treat a struct like a zero arg template for mixin purposes. --bbIt amounts to the same thing, so it just depends on which syntax you prefer. Personally, I like... struct S : M { int b; } ... meaning S is non-polymorphically inherited from M. I guess the argument against taht syntax was that it would be confusing for people from a C++ background who assume polymorphic inheritance for structs. Anyways, it's up to Walter to decide on the syntax, and he says "alias this".
Sep 03 2007
Reply to Regan,Bill Baxter wrote:Why? That's not how I would want to do it.The reason these should be structs is because sometimes you want to add in maybe one or two small data members that control operation. For instance you might have a 'compare' function in the traits and want to parameterize it by a data member to act like either less-than or greater-than. Such things should have value semantics.The proposed struct inheritance only inherits fields, not methods/functions though, right?Regan
Sep 03 2007
Bill Baxter wrote:Let us all turn our copies of WalterAndrei.pdf to page 40 where yea verily it doth say: struct M { int a; } struct S { M m; alias m this; int b; } Why not just allow mixin to do this? struct M { int a; } struct S { mixin M; int b; } That's basically the way it's done now except now it would be more like: template MMixin() { int a; } struct M { mixin M; } struct S { mixin M; int b; } Just let us treat a struct like a zero arg template for mixin purposes. --bbPerhaps because the alias itself is optional? It just brings the members of 'm' into the namespace of 'S', without requiring an explicit S.m.a dereference. On the other hand, mixin is the work of the devil :p
Aug 30 2007
Bill Baxter wrote:Let us all turn our copies of WalterAndrei.pdf to page 40 where yea verily it doth say: struct M { int a; } struct S { M m; alias m this; int b; } Why not just allow mixin to do this? struct M { int a; } struct S { mixin M; int b; } That's basically the way it's done now except now it would be more like: template MMixin() { int a; } struct M { mixin M; } struct S { mixin M; int b; } Just let us treat a struct like a zero arg template for mixin purposes. --bbTemplate mixins require that the sourcecode of the template is available to the compiler. Aliases don't. In this sense at least, aliases are cleaner. -- Reiner
Aug 30 2007
Reiner Pope wrote:Bill Baxter wrote:Also, Walter wants to get of template mixins. (That was discussed a little on the Saturday).Let us all turn our copies of WalterAndrei.pdf to page 40 where yea verily it doth say: struct M { int a; } struct S { M m; alias m this; int b; } Why not just allow mixin to do this? struct M { int a; } struct S { mixin M; int b; } That's basically the way it's done now except now it would be more like: template MMixin() { int a; } struct M { mixin M; } struct S { mixin M; int b; } Just let us treat a struct like a zero arg template for mixin purposes. --bbTemplate mixins require that the sourcecode of the template is available to the compiler. Aliases don't. In this sense at least, aliases are cleaner. -- Reiner
Aug 30 2007
Reply to Don,Also, Walter wants to get of template mixins. (That was discussed a little on the Saturday).WHAT!! They are such a wonderful solution to a number of interesting problems. Unless He plans on having macros take there place I would be vary sad to see them go. will a macro be able to add several function to a class in one shot? Several template alias to another template?
Aug 30 2007
BCS wrote:Reply to Don,I think that's the idea.Also, Walter wants to get of template mixins. (That was discussed a little on the Saturday).WHAT!! They are such a wonderful solution to a number of interesting problems. Unless He plans on having macros take there place I would be vary sad to see them go.will a macro be able to add several function to a class in one shot? Several template alias to another template?
Sep 01 2007
Don Clugston wrote:Reiner Pope wrote:Just to be clear -- I'm not saying the 'mixin M' should be a shortcut for the similar-looking template mixin. Just suggesting to reuse the keyword for a similar concept. You want to add in the members of another struct and at the same time avoid it looking like polymorphic inheritance.Bill Baxter wrote:Let us all turn our copies of WalterAndrei.pdf to page 40 where yea verily it doth say: struct M { int a; } struct S { M m; alias m this; int b; } Why not just allow mixin to do this? struct M { int a; } struct S { mixin M; int b; } That's basically the way it's done now except now it would be more like: template MMixin() { int a; } struct M { mixin M; } struct S { mixin M; int b; } Just let us treat a struct like a zero arg template for mixin purposes. --bbTemplate mixins require that the sourcecode of the template is available to the compiler. Aliases don't. In this sense at least, aliases are cleaner. -- ReinerAlso, Walter wants to get [rid] of template mixins. (That was discussed a little on the Saturday).Now that's interesting. Replaced by macros? --bb
Aug 31 2007
Bill Baxter wrote:Don Clugston wrote:I like it. It's also more consistent with the previous behavior.Reiner Pope wrote:>> -- Reiner Just to be clear -- I'm not saying the 'mixin M' should be a shortcut for the similar-looking template mixin. Just suggesting to reuse the keyword for a similar concept. You want to add in the members of another struct and at the same time avoid it looking like polymorphic inheritance.Bill Baxter wrote:Let us all turn our copies of WalterAndrei.pdf to page 40 where yea verily it doth say: struct M { int a; } struct S { M m; alias m this; int b; } Why not just allow mixin to do this? struct M { int a; } struct S { mixin M; int b; } That's basically the way it's done now except now it would be more like: template MMixin() { int a; } struct M { mixin M; } struct S { mixin M; int b; } Just let us treat a struct like a zero arg template for mixin purposes. --bbTemplate mixins require that the sourcecode of the template is available to the compiler. Aliases don't. In this sense at least, aliases are cleaner.Sounds really hilarious since I've always considered mixins to be macros in D. If you look at the new paper, the only differences between 'macro' and template+mixin are a) mixins provide only unhygienic macros, 'macro' has syntax for both cases b) template mixins can only inject declarations c) parameter types and pattern matching What I would like to see is an unification of macros and templates. I don't see any reason why templates cannot have better pattern matching or hygienic invocations. It should be pretty easy to copy that functionality from one's favourite state of the art purely functional language. Hmm, one more thing. The slides only show how pattern matching works with expressions. What about blocks of code? Will it be possible to implement a custom <insert some builtin statement here> with macros? Will all statements in D 2.0 become expressions?Also, Walter wants to get [rid] of template mixins. (That was discussed a little on the Saturday).Now that's interesting. Replaced by macros?
Aug 31 2007
Don Clugston wrote:Also, Walter wants to get of template mixins. (That was discussed a little on the Saturday).Hoorah! Hoorah! :)
Aug 31 2007
Reiner Pope wrote:Bill Baxter wrote:Huh? Explain how the above alias example would work if the compiler doesn't know the source code of what is being aliased: struct M; struct S { M m; alias m this; int b; } It's not even possible to declare m without knowing the source of M! Perhaps I misunderstood you? -- Bruno Medeiros - MSc in CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#DLet us all turn our copies of WalterAndrei.pdf to page 40 where yea verily it doth say: struct M { int a; } struct S { M m; alias m this; int b; } Why not just allow mixin to do this? struct M { int a; } struct S { mixin M; int b; } That's basically the way it's done now except now it would be more like: template MMixin() { int a; } struct M { mixin M; } struct S { mixin M; int b; } Just let us treat a struct like a zero arg template for mixin purposes. --bbTemplate mixins require that the sourcecode of the template is available to the compiler. Aliases don't. In this sense at least, aliases are cleaner. -- Reiner
Sep 01 2007
Bruno Medeiros wrote:Reiner Pope wrote:All you need is a declaration of M's interface, you don't need to distribute the source code of your implementation, whereas template mixins require that the implementation source is also available. -- ReinerBill Baxter wrote:Huh? Explain how the above alias example would work if the compiler doesn't know the source code of what is being aliased: struct M; struct S { M m; alias m this; int b; } It's not even possible to declare m without knowing the source of M! Perhaps I misunderstood you?Let us all turn our copies of WalterAndrei.pdf to page 40 where yea verily it doth say: struct M { int a; } struct S { M m; alias m this; int b; } Why not just allow mixin to do this? struct M { int a; } struct S { mixin M; int b; } That's basically the way it's done now except now it would be more like: template MMixin() { int a; } struct M { mixin M; } struct S { mixin M; int b; } Just let us treat a struct like a zero arg template for mixin purposes. --bbTemplate mixins require that the sourcecode of the template is available to the compiler. Aliases don't. In this sense at least, aliases are cleaner. -- Reiner
Sep 01 2007
Reiner Pope wrote:Bruno Medeiros wrote:You mean like ? --- foo.di --- struct M { int a; void func(); } --- ---- import foo; struct S { M m; alias m this; int b; } And then linking with a foo.obj that has an implementation for M.func? -- Bruno Medeiros - MSc in CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#DReiner Pope wrote:All you need is a declaration of M's interface, you don't need to distribute the source code of your implementation, whereas template mixins require that the implementation source is also available. -- ReinerBill Baxter wrote:Huh? Explain how the above alias example would work if the compiler doesn't know the source code of what is being aliased: struct M; struct S { M m; alias m this; int b; } It's not even possible to declare m without knowing the source of M! Perhaps I misunderstood you?Let us all turn our copies of WalterAndrei.pdf to page 40 where yea verily it doth say: struct M { int a; } struct S { M m; alias m this; int b; } Why not just allow mixin to do this? struct M { int a; } struct S { mixin M; int b; } That's basically the way it's done now except now it would be more like: template MMixin() { int a; } struct M { mixin M; } struct S { mixin M; int b; } Just let us treat a struct like a zero arg template for mixin purposes. --bbTemplate mixins require that the sourcecode of the template is available to the compiler. Aliases don't. In this sense at least, aliases are cleaner. -- Reiner
Sep 01 2007
Bruno Medeiros wrote:Reiner Pope wrote:Hum, that being the case, then yes it's different, mostly due to the fact that mixin templates always generate new instances of their content, and this "import alias" would not. Another noticeable difference would be if the content had static members: mixin templates would generate new "instances" of the static member, whereas the "import alias" would always refer to the same static member. -- Bruno Medeiros - MSc in CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#DBruno Medeiros wrote:You mean like ? --- foo.di --- struct M { int a; void func(); } --- ---- import foo; struct S { M m; alias m this; int b; } And then linking with a foo.obj that has an implementation for M.func?Reiner Pope wrote:All you need is a declaration of M's interface, you don't need to distribute the source code of your implementation, whereas template mixins require that the implementation source is also available. -- ReinerBill Baxter wrote:Huh? Explain how the above alias example would work if the compiler doesn't know the source code of what is being aliased: struct M; struct S { M m; alias m this; int b; } It's not even possible to declare m without knowing the source of M! Perhaps I misunderstood you?Let us all turn our copies of WalterAndrei.pdf to page 40 where yea verily it doth say: struct M { int a; } struct S { M m; alias m this; int b; } Why not just allow mixin to do this? struct M { int a; } struct S { mixin M; int b; } That's basically the way it's done now except now it would be more like: template MMixin() { int a; } struct M { mixin M; } struct S { mixin M; int b; } Just let us treat a struct like a zero arg template for mixin purposes. --bbTemplate mixins require that the sourcecode of the template is available to the compiler. Aliases don't. In this sense at least, aliases are cleaner. -- Reiner
Sep 01 2007