digitalmars.D - struct mixins
- Leandro Lucarella (68/68) Nov 16 2009 struct inheritance never make it into D, for a good reason: structs are
- Steven Schveighoffer (5/6) Nov 16 2009 This is a very good idea. BTW, I think conflicts should be a compile-ti...
- Leandro Lucarella (39/46) Nov 16 2009 I think compile-time error is nice and clean, but you are lost if you're
- Frank Benoit (2/2) Nov 16 2009 Reminds me of an older thread:
- Denis Koroskin (10/12) Nov 16 2009 I recall it, but I still think "alias this" is the way to go:
- Leandro Lucarella (10/27) Nov 16 2009 See how a struct mixin could add an implicit/explicit cast to the mixed ...
- Leandro Lucarella (24/26) Nov 16 2009 I think mixin can mix very well with that proposal, when the compiler se...
- div0 (20/106) Nov 16 2009 -----BEGIN PGP SIGNED MESSAGE-----
- Bill Baxter (21/117) Nov 16 2009 e
- Leandro Lucarella (16/137) Nov 16 2009 I meant to say:
- div0 (19/53) Nov 17 2009 -----BEGIN PGP SIGNED MESSAGE-----
- Bill Baxter (7/17) Nov 17 2009 I don't see why you couldn't allow alias this to give you the same
struct inheritance never make it into D, for a good reason: structs are not supposed to be polymorphic and inheritance is very tied to polymorphism. But struct inheritance is sometimes very useful for "composition", avoid an extra member when accessing to the composed type members. Example: struct A { int x; int y; } struct B { A a; int z; } B b; b.a.x = 5; A way to "fix" this is using template mixins: template Common() { int x; int y; } struct A { mixin Common; } struct B { mixin Common; int z; } B b; b.x = 5; But one can think this is even worse than the previous approach :) What if one could use a struct directly with mixin? struct A { int x; int y; } struct B { mixin A; int z; } B b; b.x = 5; I think this is nice, looks good, is backwards compatible, it might be easy to implement (not sure about that though) and can be even extended to classes (not sure about the usefulness of that either). The only problem are name collisions, but that can already happen with template mixins, right? Anyway, collisions can yield a compile error, or they might be accepted, requiring the full qualified name to access the attribute, like with classes and inheritance (you can't do a mixin of the same struct twice). Say A is updated in the future: struct A { int x; int y; int z; } b.z = 1; // changes B.z // to modify B.A.z: b.A.z = 1; I think collisions should be very rare anyways in structs. PS: For those who wonder, yes, this is inspired in the "embedding" feature of Google's Go, which is basically a mixin, but without adding template to the mix, it's just this, struct mixins. -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ ---------------------------------------------------------------------- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) ---------------------------------------------------------------------- El techo de mi cuarto lleno de universos
Nov 16 2009
On Mon, 16 Nov 2009 10:32:31 -0500, Leandro Lucarella <llucax gmail.com> wrote:What if one could use a struct directly with mixin?This is a very good idea. BTW, I think conflicts should be a compile-time error. -Steve
Nov 16 2009
Steven Schveighoffer, el 16 de noviembre a las 10:44 me escribiste:On Mon, 16 Nov 2009 10:32:31 -0500, Leandro Lucarella <llucax gmail.com> wrote:I think compile-time error is nice and clean, but you are lost if you're using a third-party struct, and the maintainer adds a new field that collides with yours. Example: struct ThirdParty { int x; } struct Mine { mixin ThirdParty; int y; } void myCode(Mine m) { m.y = 1; } If ThirdParty is changed like this: struct ThirdParty { int x; int y; } Then your code don't compile anymore and you can't fix it. Either you stop using mixin ThirdParty or you have to change your struct and *all* the code written for it. On the other hand, if you allow explicit disambiguation, you code still compiles and work as expected. You just won't use the new y variable from ThirdParty (you didn't use it before either, so that's OK). If you need to start using the new y attribute from ThirdParty, you can do it with: void myCode(Mine m) { m.y = m.ThirdParty.y; } -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ ---------------------------------------------------------------------- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) ---------------------------------------------------------------------- Yeah, I'm a great quitter. It's one of the few things I do well. I come from a long line of quitters. My father was a quitter, my grandfather was a quitter... I was raised to give up. -- George ConstanzaWhat if one could use a struct directly with mixin?This is a very good idea. BTW, I think conflicts should be a compile-time error.
Nov 16 2009
Reminds me of an older thread: http://www.digitalmars.com/d/archives/digitalmars/D/Implicit_castable_structs_64764.html
Nov 16 2009
On Mon, 16 Nov 2009 18:58:42 +0300, Frank Benoit <keinfarbton googlemail.com> wrote:Reminds me of an older thread: http://www.digitalmars.com/d/archives/digitalmars/D/Implicit_castable_structs_64764.htmlI recall it, but I still think "alias this" is the way to go: struct GtkWidget{ /* data member */ } struct GtkContainer{ GtkWidget widget; // mixin GtkWidget; could also work, though // more data members alias this &widget; // how would you do the same without a named mixin? // And what's the benefit of named mixin over plain old aggregation? }
Nov 16 2009
Denis Koroskin, el 16 de noviembre a las 19:03 me escribiste:On Mon, 16 Nov 2009 18:58:42 +0300, Frank Benoit <keinfarbton googlemail.com> wrote:See how a struct mixin could add an implicit/explicit cast to the mixed in structs. -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ ---------------------------------------------------------------------- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) ---------------------------------------------------------------------- Con vos hay pica, patovica! -- Sidharta KiwiReminds me of an older thread: http://www.digitalmars.com/d/archives/digitalmars/D/Implicit_castable_structs_64764.htmlI recall it, but I still think "alias this" is the way to go: struct GtkWidget{ /* data member */ } struct GtkContainer{ GtkWidget widget; // mixin GtkWidget; could also work, though // more data members alias this &widget; // how would you do the same without a named mixin? // And what's the benefit of named mixin over plain old aggregation? }
Nov 16 2009
Frank Benoit, el 16 de noviembre a las 16:58 me escribiste:Reminds me of an older thread: http://www.digitalmars.com/d/archives/digitalmars/D/Implicit_castable_structs_64764.htmlI think mixin can mix very well with that proposal, when the compiler sees a struct mixin, it can automatically provide an {im,ex}plicit cast to the mixed in type, adjusting the pointer: struct A { int x; } struct B { int y; } struct C { mixin A; mixin B; } C* c = new C; A* a = cast(A*) c; // points to c B* a = cast(B*) c; // points to c + A.sizeof -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ ---------------------------------------------------------------------- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) ---------------------------------------------------------------------- Cómo ser inconmensurablemente atractivo a la mujer del sexo opuesto. -- Libro de autoayuda de Hector Mesina.
Nov 16 2009
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Leandro Lucarella wrote:struct inheritance never make it into D, for a good reason: structs are not supposed to be polymorphic and inheritance is very tied to polymorphism. But struct inheritance is sometimes very useful for "composition", avoid an extra member when accessing to the composed type members. Example: struct A { int x; int y; } struct B { A a; int z; } B b; b.a.x = 5; A way to "fix" this is using template mixins: template Common() { int x; int y; } struct A { mixin Common; } struct B { mixin Common; int z; } B b; b.x = 5; But one can think this is even worse than the previous approach :) What if one could use a struct directly with mixin? struct A { int x; int y; } struct B { mixin A; int z; } B b; b.x = 5; I think this is nice, looks good, is backwards compatible, it might be easy to implement (not sure about that though) and can be even extended to classes (not sure about the usefulness of that either). The only problem are name collisions, but that can already happen with template mixins, right? Anyway, collisions can yield a compile error, or they might be accepted, requiring the full qualified name to access the attribute, like with classes and inheritance (you can't do a mixin of the same struct twice). Say A is updated in the future: struct A { int x; int y; int z; } b.z = 1; // changes B.z // to modify B.A.z: b.A.z = 1; I think collisions should be very rare anyways in structs. PS: For those who wonder, yes, this is inspired in the "embedding" feature of Google's Go, which is basically a mixin, but without adding template to the mix, it's just this, struct mixins.vote++ I was going to suggest it when I finished my spirit port, but I was too lazy to in the end. It would be very handy as currently the only way support multiple policies is to use member vars which are basically pointers to empty classes, so it looks rather more ugly than it needs to be. Mixin should really go hog wild I think and let you mixin anything anywhere. - -- My enormous talent is exceeded only by my outrageous laziness. http://www.ssTk.co.uk -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.7 (MingW32) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iD8DBQFLAajpT9LetA9XoXwRAkDsAKCZ59OTxLlqoKUZFVMkElBOED/ihwCfbBf9 txVFtwPyKxkrYmYHzVeETI4= =o8VR -----END PGP SIGNATURE-----
Nov 16 2009
On Mon, Nov 16, 2009 at 11:32 AM, div0 <div0 users.sourceforge.net> wrote:-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Leandro Lucarella wrote:tostruct inheritance never make it into D, for a good reason: structs are not supposed to be polymorphic and inheritance is very tied to polymorphism. But struct inheritance is sometimes very useful for "composition", avoid an extra member when accessing to the composed type members. Example: struct A { =A0 =A0 =A0 int x; =A0 =A0 =A0 int y; } struct B { =A0 =A0 =A0 A a; =A0 =A0 =A0 int z; } B b; b.a.x =3D 5; A way to "fix" this is using template mixins: template Common() { =A0 =A0 =A0 int x; =A0 =A0 =A0 int y; } struct A { =A0 =A0 =A0 mixin Common; } struct B { =A0 =A0 =A0 mixin Common; =A0 =A0 =A0 int z; } B b; b.x =3D 5; But one can think this is even worse than the previous approach :) What if one could use a struct directly with mixin? struct A { =A0 =A0 =A0 int x; =A0 =A0 =A0 int y; } struct B { =A0 =A0 =A0 mixin A; =A0 =A0 =A0 int z; } B b; b.x =3D 5; I think this is nice, looks good, is backwards compatible, it might be easy to implement (not sure about that though) and can be even extended =eclasses (not sure about the usefulness of that either). The only problem are name collisions, but that can already happen with template mixins, right? Anyway, collisions can yield a compile error, or they might be accepted, requiring the full qualified name to access the attribute, like with classes and inheritance (you can't do a mixin of th=resame struct twice). Say A is updated in the future: struct A { =A0 =A0 =A0 int x; =A0 =A0 =A0 int y; =A0 =A0 =A0 int z; } b.z =3D 1; // changes B.z // to modify B.A.z: b.A.z =3D 1; I think collisions should be very rare anyways in structs. PS: For those who wonder, yes, this is inspired in the "embedding" featu=re. I have wanted this kind of thing before too. I can't recall the exact reason, but it had something to do with traits structs. I hit it when I was porting OpenMesh to D. There's some base set of traits provided by the library as a struct that you may want to add too in user code. But I think "alias this" would probably serve that need just fine. What use cases are served by the mixin that 'alias this' does not? It looks like this was an attempt to explain, but I don't understand: "See how a struct mixin could add an implicit/explicit cast to the mixed in structs." I guess mixin struct could allow a kind of static multiple inheritance. But if that's desirable, then probably alias this should just be extended to enable that. Seems like the two are so similar that whatever alias this lacks in features could just be added rather than introducing a new construct. --bb=A0 =A0 of Google's Go, which is basically a mixin, but without adding =A0 =A0 template to the mix, it's just this, struct mixins.vote++ I was going to suggest it when I finished my spirit port, but I was too lazy to in the end. It would be very handy as currently the only way support multiple policies is to use member vars which are basically pointers to empty classes, so it looks rather more ugly than it needs to be. Mixin should really go hog wild I think and let you mixin anything anywhe=
Nov 16 2009
Bill Baxter, el 16 de noviembre a las 13:08 me escribiste:On Mon, Nov 16, 2009 at 11:32 AM, div0 <div0 users.sourceforge.net> wrote:I meant to say: "See how a struct mixin could add an implicit/explicit cast to the mixed in structs in my previous mail." Which would be: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=101242 Maybe I don't fully understand alias this. Does alias this can do that?-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Leandro Lucarella wrote:I have wanted this kind of thing before too. I can't recall the exact reason, but it had something to do with traits structs. I hit it when I was porting OpenMesh to D. There's some base set of traits provided by the library as a struct that you may want to add too in user code. But I think "alias this" would probably serve that need just fine. What use cases are served by the mixin that 'alias this' does not? It looks like this was an attempt to explain, but I don't understand: "See how a struct mixin could add an implicit/explicit cast to the mixed in structs."struct inheritance never make it into D, for a good reason: structs are not supposed to be polymorphic and inheritance is very tied to polymorphism. But struct inheritance is sometimes very useful for "composition", avoid an extra member when accessing to the composed type members. Example: struct A { int x; int y; } struct B { A a; int z; } B b; b.a.x = 5; A way to "fix" this is using template mixins: template Common() { int x; int y; } struct A { mixin Common; } struct B { mixin Common; int z; } B b; b.x = 5; But one can think this is even worse than the previous approach :) What if one could use a struct directly with mixin? struct A { int x; int y; } struct B { mixin A; int z; } B b; b.x = 5; I think this is nice, looks good, is backwards compatible, it might be easy to implement (not sure about that though) and can be even extended to classes (not sure about the usefulness of that either). The only problem are name collisions, but that can already happen with template mixins, right? Anyway, collisions can yield a compile error, or they might be accepted, requiring the full qualified name to access the attribute, like with classes and inheritance (you can't do a mixin of the same struct twice). Say A is updated in the future: struct A { int x; int y; int z; } b.z = 1; // changes B.z // to modify B.A.z: b.A.z = 1; I think collisions should be very rare anyways in structs. PS: For those who wonder, yes, this is inspired in the "embedding" feature of Google's Go, which is basically a mixin, but without adding template to the mix, it's just this, struct mixins.vote++ I was going to suggest it when I finished my spirit port, but I was too lazy to in the end. It would be very handy as currently the only way support multiple policies is to use member vars which are basically pointers to empty classes, so it looks rather more ugly than it needs to be. Mixin should really go hog wild I think and let you mixin anything anywhere.I guess mixin struct could allow a kind of static multiple inheritance. But if that's desirable, then probably alias this should just be extended to enable that. Seems like the two are so similar that whatever alias this lacks in features could just be added rather than introducing a new construct.I really didn't thought about alias this when making this proposal (I had this problem using D1, I'm not using D2 much), so maybe you are right. -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ ---------------------------------------------------------------------- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) ---------------------------------------------------------------------- EL "PITUFO ENRIQUE" LLEGO A LA BAILANTA -- Crónica TV
Nov 16 2009
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Bill Baxter wrote:On Mon, Nov 16, 2009 at 11:32 AM, div0 <div0 users.sourceforge.net> wrote:<snip>Well at the moment you only get one alias this. I suppose you could allow multiple alias this, but then what happens with multiple symbols with the same name? At least with mixins you can disambiguate. Still using member vars worked for me; there's more important stuff to be doing at the moment. - -- My enormous talent is exceeded only by my outrageous laziness. http://www.ssTk.co.uk -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.7 (MingW32) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iD8DBQFLAvMpT9LetA9XoXwRAuIZAKCyRCfzrXGEPJeH7n1zC/UcrHvsKACdFX8F qp4lpEqHtf0ruF0XSHVQUXM= =2zvO -----END PGP SIGNATURE-----I have wanted this kind of thing before too. I can't recall the exact reason, but it had something to do with traits structs. I hit it when I was porting OpenMesh to D. There's some base set of traits provided by the library as a struct that you may want to add too in user code. But I think "alias this" would probably serve that need just fine. What use cases are served by the mixin that 'alias this' does not? It looks like this was an attempt to explain, but I don't understand: "See how a struct mixin could add an implicit/explicit cast to the mixed in structs." I guess mixin struct could allow a kind of static multiple inheritance. But if that's desirable, then probably alias this should just be extended to enable that. Seems like the two are so similar that whatever alias this lacks in features could just be added rather than introducing a new construct. --bbvote++ I was going to suggest it when I finished my spirit port, but I was too lazy to in the end. It would be very handy as currently the only way support multiple policies is to use member vars which are basically pointers to empty classes, so it looks rather more ugly than it needs to be. Mixin should really go hog wild I think and let you mixin anything anywhere.
Nov 17 2009
On Tue, Nov 17, 2009 at 11:02 AM, div0 <div0 users.sourceforge.net> wrote:I don't see why you couldn't allow alias this to give you the same disambiguation capability. Or just get rid of alias this in favor of type mixins. Doesn't really matter to me. But I'm not seeing any reason to have both constructs when they do almost the same thing. --bbI guess mixin struct could allow a kind of static multiple inheritance. =A0But if that's desirable, then probably alias this should just be extended to enable that. =A0Seems like the two are so similar that whatever alias this lacks in features could just be added rather than introducing a new construct. --bbWell at the moment you only get one alias this. I suppose you could allow multiple alias this, but then what happens with multiple symbols with the same name? At least with mixins you can disambiguate.
Nov 17 2009