D - COMMENTS: Mixins Specification
- fred (100/100) Apr 29 2004 charset="iso-8859-1"
- J Anderson (5/8) Apr 29 2004 I added this to
- Matthew (167/167) Apr 29 2004 Wow, I hadn't realised that this had got so serious!
- Hauke Duden (22/42) Apr 30 2004 I like it. It is simple and exactly what you need to put mixins to good
- Matthew (11/53) Apr 30 2004 DTL,
- Hauke Duden (17/30) Apr 30 2004 I think the same rules that are used when a class uses multiple mixins
- Matthew (5/34) Apr 30 2004 signatures. I
- Hauke Duden (4/22) Apr 30 2004 Well, if A is the mixin whose "foo" you want to call, then the syntax
- J Anderson (37/106) Apr 30 2004 Just out of interest: It appears to me that mixins (the class part) are
- Matthew (21/147) Apr 30 2004 DTL,
- J Anderson (4/14) Apr 30 2004 I thought there was a reason, thanks.
- Patrick Down (17/34) Apr 30 2004 Real work has been keeping me busy for 14 days straight here but
- Matthew (15/53) Apr 30 2004 DTL,
- Ben Hinkle (12/18) Apr 30 2004 I also agree it should go in the body. To quote your description of mixi...
- Matthew (14/27) Apr 30 2004 But mixins, according to my definition, have nothing to do with member d...
- Russ Lewis (5/20) May 04 2004 It seems like we could expand the capabilities of mixins later if
- Russ Lewis (30/237) May 04 2004 Please clarify my understanding here. It sounds like mixins, as you are...
- Matthew (32/270) May 04 2004 Will do ..
- Russ Lewis (10/46) May 04 2004 What I was trying to illustrate is that you can define a template which
- Matthew (6/52) May 04 2004 thoroughly?
- Achilleas Margaritis (4/50) May 05 2004 thoroughly?
charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable I would like to proposed the following specification for Mixins be = included as part of Version 1.0=20 D Programming Language specification. All comments are welcomed. MIXINS SPECIFICATION Version 0.1 Introduction What are mixins ? A mixin is a class-like entity whose methods/fields are mixed-in to the = mixing class just=20 as if the author of that class had written them manually. As Matthew so neatly put it (see = http://www.digitalmars.com/drn-bin/wwwnews?D/28348 ) Why do we need them ? The rational for Mixins is quite compelling... One of the greatest shortcomings of the C++ language from a Object = Oriented perspective,=20 is that there is no language support for Aggregated Objects. As such, = Aggregation has to be=20 performed programatically, often (incorrectly) using the inheritance = mechanism as a coding=20 shortcut. By including language support we provide a direct correlation = between OOD using=20 modeling techniques like UML, and OOP. Background Please read the following; http://www.digitalmars.com/drn-bin/wwwnews?D/28455 http://www.digitalmars.com/drn-bin/wwwnews?D/28511 http://www.digitalmars.com/drn-bin/wwwnews?D/28553 Lexical and as well as=20 Syntax There are a number of syntax alternatives that could be incorporated. Alternative A: class <identifier> [: <inherited-class>] For example; class Lamp : Light { this() { super(); =20 cBody(); // Body construction cGlobe(); // Globe construction cPowerCord(); // PowerCord construction cSwitch(cGlobe,cPowerCord); // Switch construction } }; Alternative B: class <identifier> [: <inherited-class>] [, <aggregated-class> <local-identifier>]*]=20 For example; class Lamp : Light , Switch cSwitch=20 , Globe cGlobe=20 , PowerCord cPowerCord { this() { super(); cBody(); // Body construction cGlobe(); // Globe construction cPowerCord(); // PowerCord construction cSwitch(cGlobe,cPowerCord); // Switch construction } }; Semantics The rules for Mixin variables should be the same as class member = declarations, except Mixins allow the interfaces of the aggregated class to be included as = part of the mixing class. This fact means that it is possible to have multiple versions of the = same member name=20 within a mixing class. I propose a simple precedence rule, where the member defined in the = class overrides those=20 defined in the aggregated class, and those in the aggregated classes are = assigned according=20 to the order they are declared. If this was to take place, a compiler = warning message stating=20 "that member X of aggregated class A is taking precedence over that in = aggregated class B"=20 should be displayed in the error log. Note: there are probably other things that will need to be considered = here ! Conclusion Mixins permit externally declare classes to be used as part of a class, = and in so doing provides a real alternative to the Multiple Inheritance option provided for in = the C++ language. As such, this=20 relatively insignificant addition to the language should greatly enhance = the overall flexibility of the=20 D Programming Language.=20 Comments !
Apr 29 2004
fred wrote:I would like to proposed the following specification for Mixins be included as part of Version 1.0 D Programming Language specification. /All comments are welcomed./I added this to http://www.prowiki.org/wiki4d/wiki.cgi?FeatureRequestList/Mixins. -- -Anderson: http://badmama.com.au/~anderson/
Apr 29 2004
Wow, I hadn't realised that this had got so serious! I've been chatting with Walter about a mixins syntax to serve the needs of DTL, but had (carelessly / selfishly / stupidly / ...) not put it up on the group, as I didn't have time for a debate (which I still don't). Roughly, here's my proposal, which, at first glance, appears to be quite a different kettle of fish to what you're talking about: // - Mixins define class/instance methods. // - Mixins do not define *any* instance fields. (Not sure about static fields - what do you think?) // - Mixin methods are added into the mixing class as if the user had typed them in // - Mixins have *no* polymorphic aspects whatsoever. Two classes that each mix // the same mixin are nonetheless completely unrelated // - Mixin methods may "become" polymorphic with respect to any interface(s) that the mixing class is "implement"ing // - If the mixing class already contains a method of the same signature, that "overrides" - prevents incorporation - of that mixin method. Syntax: mixin Ranges(C) // C is the mixing class. { private: typedef C.value_type value_type; // A convenience for the mixin implementation, and also a constraint on C typedef C.index_type index_type; // A convenience for the mixin implementation, and also a constraint on C public: boolean contains(value_type comperand) { foreach(value_type v; cast(C)(this)) // How to get to the real, gestalt, entity. foreach acts as a constraint on C { if(v == comperand) { return cast(boolean)(true); } } return cast(boolean)(false); } . . . } And is used as follows (as in the DTL classes, which require only that the mixing class has value_type and index_type member types, and be freachable): template List(T, B = EmptyBase) { public class List : B // base class , mixes Ranges // Note: do not need to specify mixing class, since it cannot be ambiguous. { } } Note that a mixin could also be a template, but needn't be. In a sense, it's already a template, as it's parameterised by one (and only one) type, its mixing class. Clearly, there are some differences between your proposal and mine: minor: minor issue, and will be whatever Walter deems most unambiguous and easy to parse major: - you allow for mixins to provide fields - you allow mixins to introduce a different polymorphic nature to their mixing class - you allow mixins to have constructors, which I do not I disagree with all of these, since it seems that your mixin design is almost a halfway house between SI and MI and, although I understand the motivation, I think we'll be in murky territory. Of course, my perspective may well be covered by my needs. ;) Matthew "fred" <info fleet-manage.com> wrote in message news:c6s9ck$7go$1 digitaldaemon.com... I would like to proposed the following specification for Mixins be included as part of Version 1.0 D Programming Language specification. All comments are welcomed. MIXINS SPECIFICATION Version 0.1 Introduction What are mixins ? A mixin is a class-like entity whose methods/fields are mixed-in to the mixing class just as if the author of that class had written them manually. As Matthew so neatly put it (see http://www.digitalmars.com/drn-bin/wwwnews?D/28348 ) Why do we need them ? The rational for Mixins is quite compelling... One of the greatest shortcomings of the C++ language from a Object Oriented perspective, is that there is no language support for Aggregated Objects. As such, Aggregation has to be performed programatically, often (incorrectly) using the inheritance mechanism as a coding shortcut. By including language support we provide a direct correlation between OOD using modeling techniques like UML, and OOP. Background Please read the following; http://www.digitalmars.com/drn-bin/wwwnews?D/28455 http://www.digitalmars.com/drn-bin/wwwnews?D/28511 http://www.digitalmars.com/drn-bin/wwwnews?D/28553 Lexical well as Syntax There are a number of syntax alternatives that could be incorporated. Alternative A: class <identifier> [: <inherited-class>] For example; class Lamp : Light { this() { super(); cBody(); // Body construction cGlobe(); // Globe construction cPowerCord(); // PowerCord construction cSwitch(cGlobe,cPowerCord); // Switch construction } }; Alternative B: class <identifier> [: <inherited-class>] [, <aggregated-class> <local-identifier>]*] For example; class Lamp : Light , Switch cSwitch , Globe cGlobe , PowerCord cPowerCord { this() { super(); cBody(); // Body construction cGlobe(); // Globe construction cPowerCord(); // PowerCord construction cSwitch(cGlobe,cPowerCord); // Switch construction } }; Semantics The rules for Mixin variables should be the same as class member declarations, except Mixins allow the interfaces of the aggregated class to be included as part of the mixing class. This fact means that it is possible to have multiple versions of the same member name within a mixing class. I propose a simple precedence rule, where the member defined in the class overrides those defined in the aggregated class, and those in the aggregated classes are assigned according to the order they are declared. If this was to take place, a compiler warning message stating "that member X of aggregated class A is taking precedence over that in aggregated class B" should be displayed in the error log. Note: there are probably other things that will need to be considered here ! Conclusion Mixins permit externally declare classes to be used as part of a class, and in so doing provides a real alternative to the Multiple Inheritance option provided for in the C++ language. As such, this relatively insignificant addition to the language should greatly enhance the overall flexibility of the D Programming Language. Comments !
Apr 29 2004
Matthew wrote:Wow, I hadn't realised that this had got so serious! I've been chatting with Walter about a mixins syntax to serve the needs of DTL, but had (carelessly / selfishly / stupidly / ...) not put it up on the group, as I didn't have time for a debate (which I still don't). Roughly, here's my proposal, which, at first glance, appears to be quite a different kettle of fish to what you're talking about: // - Mixins define class/instance methods. // - Mixins do not define *any* instance fields. (Not sure about static fields - what do you think?) // - Mixin methods are added into the mixing class as if the user had typed them in // - Mixins have *no* polymorphic aspects whatsoever. Two classes that each mix // the same mixin are nonetheless completely unrelated // - Mixin methods may "become" polymorphic with respect to any interface(s) that the mixing class is "implement"ing // - If the mixing class already contains a method of the same signature, that "overrides" - prevents incorporation - of that mixin method.I like it. It is simple and exactly what you need to put mixins to good use. Especially the fact that it doesn't change the classes type will prevent a lot of headaches. One other thing may be important, though. I think mixins should be combinable to form new mixins (i.e. some kind of multiple inheritance between mixins but without any type issues). I mostly want mixins to be able to conveniently provide default implementations for interfaces. And since interfaces form a hierarchy, the implementations of more specialized interfaces could then re-use implementations of the general interfaces. The implementation shouldn't be much of a problem since mixins are "typeless", so there can be none of that multiple inheritance chaos we know from C++. It would be the same as simply copying all the code from the different mixins into a new mixin, but allowing the newly created mixin to overwrite methods already defined in one of the base mixins. Note that this simply means that mixins can mix-in other mixins in the same way that classes can. Example: mixin A(X) {...} mixin B(X) {...} mixin C(X) mixes A,B {...}
Apr 30 2004
"Hauke Duden" <H.NS.Duden gmx.net> wrote in message news:c6t7gs$1m30$1 digitaldaemon.com...Matthew wrote:DTL,Wow, I hadn't realised that this had got so serious! I've been chatting with Walter about a mixins syntax to serve the needs ofasbut had (carelessly / selfishly / stupidly / ...) not put it up on the group,fields -I didn't have time for a debate (which I still don't). Roughly, here's my proposal, which, at first glance, appears to be quite a different kettle of fish to what you're talking about: // - Mixins define class/instance methods. // - Mixins do not define *any* instance fields. (Not sure about staticthemwhat do you think?) // - Mixin methods are added into the mixing class as if the user had typedmixin // - Mixins have *no* polymorphic aspects whatsoever. Two classes that eachthat// the same mixin are nonetheless completely unrelated // - Mixin methods may "become" polymorphic with respect to any interface(s)thatthe mixing class is "implement"ing // - If the mixing class already contains a method of the same signature,That seems reasonable, except where they had methods with the same signatures. I don't like the DAG crap that would transpire as a result."overrides" - prevents incorporation - of that mixin method.I like it. It is simple and exactly what you need to put mixins to good use. Especially the fact that it doesn't change the classes type will prevent a lot of headaches. One other thing may be important, though. I think mixins should be combinable to form new mixins (i.e. some kind of multiple inheritance between mixins but without any type issues). I mostly want mixins to be able to conveniently provide default implementations for interfaces. And since interfaces form a hierarchy, the implementations of more specialized interfaces could then re-use implementations of the general interfaces. The implementation shouldn't be much of a problem since mixins are "typeless", so there can be none of that multiple inheritance chaos we know from C++. It would be the same as simply copying all the code from the different mixins into a new mixin, but allowing the newly created mixin to overwrite methods already defined in one of the base mixins. Note that this simply means that mixins can mix-in other mixins in the same way that classes can. Example: mixin A(X) {...} mixin B(X) {...} mixin C(X) mixes A,B {...}
Apr 30 2004
Matthew wrote:I think the same rules that are used when a class uses multiple mixins should apply. How is it handled there? The optimal thing would be if such conflicts are silently ignored if the function's code is the same in all mixins. Might be a little complicated to implement though (or it may be a simple memcmp - probably only Walter knows). Otherwise I see two solutions: 1) it is an error and the class must override such functions 2) use a simple precedence rule, like first mixin wins (according to the order in which they are mentioned in the class definition). I like this one because of its simplicity. One could argue that it can hide mistakes, but it is basically the same thing as the rule that class methods win over mixin methods. I.e. "read the class definition from left to right and use the first matching method you find in the mentioned entities". HaukeNote that this simply means that mixins can mix-in other mixins in the same way that classes can. Example: mixin A(X) {...} mixin B(X) {...} mixin C(X) mixes A,B {...}That seems reasonable, except where they had methods with the same signatures. I don't like the DAG crap that would transpire as a result.
Apr 30 2004
"Hauke Duden" <H.NS.Duden gmx.net> wrote in message news:c6tuu6$2ukn$1 digitaldaemon.com...Matthew wrote:signatures. INote that this simply means that mixins can mix-in other mixins in the same way that classes can. Example: mixin A(X) {...} mixin B(X) {...} mixin C(X) mixes A,B {...}That seems reasonable, except where they had methods with the sameOf course! Perfect! All we need is a way to say "super" for a given mixin.don't like the DAG crap that would transpire as a result.I think the same rules that are used when a class uses multiple mixins should apply. How is it handled there? The optimal thing would be if such conflicts are silently ignored if the function's code is the same in all mixins. Might be a little complicated to implement though (or it may be a simple memcmp - probably only Walter knows). Otherwise I see two solutions: 1) it is an error and the class must override such functions2) use a simple precedence rule, like first mixin wins (according to the order in which they are mentioned in the class definition). I like this one because of its simplicity. One could argue that it can hide mistakes, but it is basically the same thing as the rule that class methods win over mixin methods. I.e. "read the class definition from left to right and use the first matching method you find in the mentioned entities".Too complex and easy to get wrong.
Apr 30 2004
Matthew wrote:Well, if A is the mixin whose "foo" you want to call, then the syntax A.foo() comes to mind ;). HaukeOf course! Perfect! All we need is a way to say "super" for a given mixin.Otherwise I see two solutions: 1) it is an error and the class must override such functionsNote that this simply means that mixins can mix-in other mixins in the same way that classes can. Example: mixin A(X) {...} mixin B(X) {...} mixin C(X) mixes A,B {...}That seems reasonable, except where they had methods with the same
Apr 30 2004
Matthew wrote:Wow, I hadn't realised that this had got so serious! I've been chatting with Walter about a mixins syntax to serve the needs of DTL, but had (carelessly / selfishly / stupidly / ...) not put it up on the group, as I didn't have time for a debate (which I still don't). Roughly, here's my proposal, which, at first glance, appears to be quite a different kettle of fish to what you're talking about: // - Mixins define class/instance methods. // - Mixins do not define *any* instance fields. (Not sure about static fields - what do you think?) // - Mixin methods are added into the mixing class as if the user had typed them in // - Mixins have *no* polymorphic aspects whatsoever. Two classes that each mix // the same mixin are nonetheless completely unrelated // - Mixin methods may "become" polymorphic with respect to any interface(s) that the mixing class is "implement"ing // - If the mixing class already contains a method of the same signature, that "overrides" - prevents incorporation - of that mixin method. Syntax: mixin Ranges(C) // C is the mixing class. { private: typedef C.value_type value_type; // A convenience for the mixin implementation, and also a constraint on C typedef C.index_type index_type; // A convenience for the mixin implementation, and also a constraint on C public: boolean contains(value_type comperand) { foreach(value_type v; cast(C)(this)) // How to get to the real, gestalt, entity. foreach acts as a constraint on C { if(v == comperand) { return cast(boolean)(true); } } return cast(boolean)(false); } . . . } And is used as follows (as in the DTL classes, which require only that the mixing class has value_type and index_type member types, and be freachable): template List(T, B = EmptyBase) { public class List : B // base class , mixes Ranges // Note: do not need to specify mixing class, since it cannot be ambiguous. { } } Note that a mixin could also be a template, but needn't be. In a sense, it's already a template, as it's parameterised by one (and only one) type, its mixing class. Clearly, there are some differences between your proposal and mine: minor: minor issue, and will be whatever Walter deems most unambiguous and easy to parse major: - you allow for mixins to provide fields - you allow mixins to introduce a different polymorphic nature to their mixing class - you allow mixins to have constructors, which I do not I disagree with all of these, since it seems that your mixin design is almost a halfway house between SI and MI and, although I understand the motivation, I think we'll be in murky territory. Of course, my perspective may well be covered by my needs. ;) MatthewJust out of interest: It appears to me that mixins (the class part) are very similar to structs? Why couldn't structs be used as mixins instead? I mean something like: struct Ranges(C) // C is the mixing class. { private: typedef C.value_type value_type; // A convenience for the mixin implementation, and also a constraint on C typedef C.index_type index_type; // A convenience for the mixin implementation, and also a constraint on C public: boolean contains(value_type comperand) { foreach(value_type v; cast(C)(this)) // How to get to the real, gestalt, entity. foreach acts as a constraint on C { if(v == comperand) { return cast(boolean)(true); } } return cast(boolean)(false); } . . . } template List(T, B = EmptyBase) { public class List : B // base class , mixes Ranges // Note: do not need to specify mixing class, since it cannot be ambiguous. { } } -- -Anderson: http://badmama.com.au/~anderson/
Apr 30 2004
"J Anderson" <REMOVEanderson badmama.com.au> wrote in message news:c6t9ri$1pfq$1 digitaldaemon.com...Matthew wrote:DTL,Wow, I hadn't realised that this had got so serious! I've been chatting with Walter about a mixins syntax to serve the needs ofasbut had (carelessly / selfishly / stupidly / ...) not put it up on the group,fields -I didn't have time for a debate (which I still don't). Roughly, here's my proposal, which, at first glance, appears to be quite a different kettle of fish to what you're talking about: // - Mixins define class/instance methods. // - Mixins do not define *any* instance fields. (Not sure about staticthemwhat do you think?) // - Mixin methods are added into the mixing class as if the user had typedmixin // - Mixins have *no* polymorphic aspects whatsoever. Two classes that eachthat// the same mixin are nonetheless completely unrelated // - Mixin methods may "become" polymorphic with respect to any interface(s)gestalt,the mixing class is "implement"ing // - If the mixing class already contains a method of the same signature, that "overrides" - prevents incorporation - of that mixin method. Syntax: mixin Ranges(C) // C is the mixing class. { private: typedef C.value_type value_type; // A convenience for the mixin implementation, and also a constraint on C typedef C.index_type index_type; // A convenience for the mixin implementation, and also a constraint on C public: boolean contains(value_type comperand) { foreach(value_type v; cast(C)(this)) // How to get to the real,mixingentity. foreach acts as a constraint on C { if(v == comperand) { return cast(boolean)(true); } } return cast(boolean)(false); } . . . } And is used as follows (as in the DTL classes, which require only that theitclass has value_type and index_type member types, and be freachable): template List(T, B = EmptyBase) { public class List : B // base class , mixes Ranges // Note: do not need to specify mixing class, sincemixingcannot be ambiguous. { } } Note that a mixin could also be a template, but needn't be. In a sense, it's already a template, as it's parameterised by one (and only one) type, itsminorclass. Clearly, there are some differences between your proposal and mine: minor:aissue, and will be whatever Walter deems most unambiguous and easy to parse major: - you allow for mixins to provide fields - you allow mixins to introduce a different polymorphic nature to their mixing class - you allow mixins to have constructors, which I do not I disagree with all of these, since it seems that your mixin design is almostBecause a struct does not have a mixing class. If you made the struct a template, that would mean that mixins could not be templates - which they can in my proposal - because the "template" syntax would already be used in making it a mixin. There are several other reasons why it can't be so, but that's good enough.halfway house between SI and MI and, although I understand the motivation, I think we'll be in murky territory. Of course, my perspective may well be covered by my needs. ;) MatthewJust out of interest: It appears to me that mixins (the class part) are very similar to structs? Why couldn't structs be used as mixins instead?I mean something like: struct Ranges(C) // C is the mixing class. { private: typedef C.value_type value_type; // A convenience for the mixin implementation, and also a constraint on C typedef C.index_type index_type; // A convenience for the mixin implementation, and also a constraint on C public: boolean contains(value_type comperand) { foreach(value_type v; cast(C)(this)) // How to get to the real,gestalt,entity. foreach acts as a constraint on C { if(v == comperand) { return cast(boolean)(true); } } return cast(boolean)(false); } . . . } template List(T, B = EmptyBase) { public class List : B // base class , mixes Ranges // Note: do not need to specify mixing class, sinceitcannot be ambiguous. { } } -- -Anderson: http://badmama.com.au/~anderson/
Apr 30 2004
Matthew wrote:I thought there was a reason, thanks. -- -Anderson: http://badmama.com.au/~anderson/Just out of interest: It appears to me that mixins (the class part) are very similar to structs? Why couldn't structs be used as mixins instead?Because a struct does not have a mixing class. If you made the struct a template, that would mean that mixins could not be templates - which they can in my proposal - because the "template" syntax would already be used in making it a mixin. There are several other reasons why it can't be so, but that's good enough.
Apr 30 2004
In article <c6sb58$a39$1 digitaldaemon.com>, Matthew says...Wow, I hadn't realised that this had got so serious! I've been chatting with Walter about a mixins syntax to serve the needs of DTL, but had (carelessly / selfishly / stupidly / ...) not put it up on the group, as I didn't have time for a debate (which I still don't).Real work has been keeping me busy for 14 days straight here but I will make a few comments.Roughly, here's my proposal, which, at first glance, appears to be quite a different kettle of fish to what you're talking about: // - Mixins define class/instance methods. // - Mixins do not define *any* instance fields. (Not sure about static fields - what do you think?)This seems a little arbitrary. Why should this restriction be made especially give the implementation just below. I can think of a number of reason to want fields.// - Mixin methods are added into the mixing class as if the user had typed them inYes// - Mixins have *no* polymorphic aspects whatsoever. Two classes that each mix // the same mixin are nonetheless completely unrelatedYes// - Mixin methods may "become" polymorphic with respect to any interface(s) that the mixing class is "implement"ing // - If the mixing class already contains a method of the same signature, that "overrides" - prevents incorporation - of that mixin method.Does this include methods from a base of the class? I would say that any directly defined members of the class take precedence over the mixin method but the mixin method take precedence over and base class method. My view point on mixins is in line with Fred's post. ( See my reply to him. ) The major difference is that I think the mixin declaration needs to go into the class body not the header. The reason for this is that I think mixins should be able to be able to be parameterized by items from the declaration scope.
Apr 30 2004
"Patrick Down" <Patrick_member pathlink.com> wrote in message news:c6ts0i$2pjn$1 digitaldaemon.com...In article <c6sb58$a39$1 digitaldaemon.com>, Matthew says...DTL,Wow, I hadn't realised that this had got so serious! I've been chatting with Walter about a mixins syntax to serve the needs ofasbut had (carelessly / selfishly / stupidly / ...) not put it up on the group,fields -I didn't have time for a debate (which I still don't).Real work has been keeping me busy for 14 days straight here but I will make a few comments.Roughly, here's my proposal, which, at first glance, appears to be quite a different kettle of fish to what you're talking about: // - Mixins define class/instance methods. // - Mixins do not define *any* instance fields. (Not sure about staticI just want to avoid complexity in the compiler (and in the language), and gut feel tells me this will needlessly complicate. But then, I only want behavioural decoration. I don't care about aggregation, whereas others do.what do you think?)This seems a little arbitrary. Why should this restriction be made especially give the implementation just below. I can think of a number of reason to want fields.them// - Mixin methods are added into the mixing class as if the user had typedmixinYes// - Mixins have *no* polymorphic aspects whatsoever. Two classes that eachthat// the same mixin are nonetheless completely unrelatedYes// - Mixin methods may "become" polymorphic with respect to any interface(s)Excellent point. I agree with you, although there'd have to be a mechanism for saying that we want the base class function, something akin to "using parent_class_type::method1();" in C++the mixing class is "implement"ing // - If the mixing class already contains a method of the same signature, that "overrides" - prevents incorporation - of that mixin method.Does this include methods from a base of the class? I would say that any directly defined members of the class take precedence over the mixin method but the mixin method take precedence over and base class method.My view point on mixins is in line with Fred's post. ( See my reply to him. ) The major difference is that I think the mixin declaration needs to go into the class body not the header. The reason for this is that I think mixins should be able to be able to be parameterized by items from the declaration scope.Can you give a motivating example?
Apr 30 2004
I also agree it should go in the body. To quote your description of mixin: "Mixin methods are added into the mixing class as if the user had typed them in" and methods are typed into the body. Also since mixins have nothing to do with inheritance putting them in the same area as the superclass and interfaces is misleading. I wonder if either the "import" or "alias" keywords can be used in this context instead of making up a new keyword. In some sense mixin (as I understand it) is just snarfing the definitions of some methods from another class so it feels very close to the semantics of "import". It seems a pity to introduce a new keyword for this. Actually maybe "snarf" isn't so bad... -BenMy view point on mixins is in line with Fred's post. ( See my reply to him. ) The major difference is that I think the mixin declaration needs to go into the class body not the header. The reason for this is that I think mixins should be able to be able to be parameterized by items from the declaration scope.Can you give a motivating example?
Apr 30 2004
"Ben Hinkle" <bhinkle4 juno.com> wrote in message news:c6uj3o$sjm$1 digitaldaemon.com...But mixins, according to my definition, have nothing to do with member data whatsoever, so I would find it misleading to have them declared internal to the class. In the absence of any kind of declarative class decorators (which may well be a better alternative) I find the base list more natural even though, as you say, mixins are not involved with inheritance as we know if. (Of course, one might counter that there's nothing written in stone that the base list syntax has to mean base classes in D. You're just hung up on C++/Java syntax.) In any case, I think it's more instrumentable, and I'd hazard a guess that it's more compilable, so I stand by my proposal. {FYI: I don't like, and don't support, the use of mixins for object aggregation, so any arguments based around that are moot wrt my proposal.]I also agree it should go in the body. To quote your description of mixin: "Mixin methods are added into the mixing class as if the user had typed them in" and methods are typed into the body. Also since mixins have nothing to do with inheritance putting them in the same area as the superclass and interfaces is misleading.My view point on mixins is in line with Fred's post. ( See my reply to him. ) The major difference is that I think the mixin declaration needs to go into the class body not the header. The reason for this is that I think mixins should be able to be able to be parameterized by items from the declaration scope.Can you give a motivating example?
Apr 30 2004
Matthew wrote:It seems like we could expand the capabilities of mixins later if necessary...but it would nearly impossible to simplify them once code was out there using the feature. I agree, keep it simple for now, and we can expand it (if needed) in 2.0.fields -// - Mixins define class/instance methods. // - Mixins do not define *any* instance fields. (Not sure about staticI just want to avoid complexity in the compiler (and in the language), and gut feel tells me this will needlessly complicate. But then, I only want behavioural decoration. I don't care about aggregation, whereas others do.what do you think?)This seems a little arbitrary. Why should this restriction be made especially give the implementation just below. I can think of a number of reason to want fields.
May 04 2004
Please clarify my understanding here. It sounds like mixins, as you are describing them, are (more or less) a generalization of templates. If I understand correctly, though, they allow a few more features. But for the moment, bear with me. Could I say that the Ranges mixin could also be (hackishly) implemented like this: class Range(C) : C { ...various fields here... } And then the class which mixes it would be defined like this: template ListBase(T,B) { public class List : B // base class , mixes Ranges // Note: do not need to specify mixing class, { } } // Can you use the template shortcut syntax for a typedef? // If so, a typedef would be better hre. template class List(T, B = EmptyBase) : Range(ListBase(T,B)) {}; Obviously, this is a more hackish solution, plus it has more class overhead. Also, in this scenario, Range cannot provide implementations for members of interfaces that List might want to export. But otherwise, does it accomplish nearly the same purpose? If so, then I heartily agree with your proposal and will be very excited to get to use it! Russ Matthew wrote:Wow, I hadn't realised that this had got so serious! I've been chatting with Walter about a mixins syntax to serve the needs of DTL, but had (carelessly / selfishly / stupidly / ...) not put it up on the group, as I didn't have time for a debate (which I still don't). Roughly, here's my proposal, which, at first glance, appears to be quite a different kettle of fish to what you're talking about: // - Mixins define class/instance methods. // - Mixins do not define *any* instance fields. (Not sure about static fields - what do you think?) // - Mixin methods are added into the mixing class as if the user had typed them in // - Mixins have *no* polymorphic aspects whatsoever. Two classes that each mix // the same mixin are nonetheless completely unrelated // - Mixin methods may "become" polymorphic with respect to any interface(s) that the mixing class is "implement"ing // - If the mixing class already contains a method of the same signature, that "overrides" - prevents incorporation - of that mixin method. Syntax: mixin Ranges(C) // C is the mixing class. { private: typedef C.value_type value_type; // A convenience for the mixin implementation, and also a constraint on C typedef C.index_type index_type; // A convenience for the mixin implementation, and also a constraint on C public: boolean contains(value_type comperand) { foreach(value_type v; cast(C)(this)) // How to get to the real, gestalt, entity. foreach acts as a constraint on C { if(v == comperand) { return cast(boolean)(true); } } return cast(boolean)(false); } . . . } And is used as follows (as in the DTL classes, which require only that the mixing class has value_type and index_type member types, and be freachable): template List(T, B = EmptyBase) { public class List : B // base class , mixes Ranges // Note: do not need to specify mixing class, since it cannot be ambiguous. { } } Note that a mixin could also be a template, but needn't be. In a sense, it's already a template, as it's parameterised by one (and only one) type, its mixing class. Clearly, there are some differences between your proposal and mine: minor: minor issue, and will be whatever Walter deems most unambiguous and easy to parse major: - you allow for mixins to provide fields - you allow mixins to introduce a different polymorphic nature to their mixing class - you allow mixins to have constructors, which I do not I disagree with all of these, since it seems that your mixin design is almost a halfway house between SI and MI and, although I understand the motivation, I think we'll be in murky territory. Of course, my perspective may well be covered by my needs. ;) Matthew "fred" <info fleet-manage.com> wrote in message news:c6s9ck$7go$1 digitaldaemon.com... I would like to proposed the following specification for Mixins be included as part of Version 1.0 D Programming Language specification. All comments are welcomed. MIXINS SPECIFICATION Version 0.1 Introduction What are mixins ? A mixin is a class-like entity whose methods/fields are mixed-in to the mixing class just as if the author of that class had written them manually. As Matthew so neatly put it (see http://www.digitalmars.com/drn-bin/wwwnews?D/28348 ) Why do we need them ? The rational for Mixins is quite compelling... One of the greatest shortcomings of the C++ language from a Object Oriented perspective, is that there is no language support for Aggregated Objects. As such, Aggregation has to be performed programatically, often (incorrectly) using the inheritance mechanism as a coding shortcut. By including language support we provide a direct correlation between OOD using modeling techniques like UML, and OOP. Background Please read the following; http://www.digitalmars.com/drn-bin/wwwnews?D/28455 http://www.digitalmars.com/drn-bin/wwwnews?D/28511 http://www.digitalmars.com/drn-bin/wwwnews?D/28553 Lexical as well as Syntax There are a number of syntax alternatives that could be incorporated. Alternative A: class <identifier> [: <inherited-class>] For example; class Lamp : Light { this() { super(); cBody(); // Body construction cGlobe(); // Globe construction cPowerCord(); // PowerCord construction cSwitch(cGlobe,cPowerCord); // Switch construction } }; Alternative B: class <identifier> [: <inherited-class>] [, <aggregated-class> <local-identifier>]*] For example; class Lamp : Light , Switch cSwitch , Globe cGlobe , PowerCord cPowerCord { this() { super(); cBody(); // Body construction cGlobe(); // Globe construction cPowerCord(); // PowerCord construction cSwitch(cGlobe,cPowerCord); // Switch construction } }; Semantics The rules for Mixin variables should be the same as class member declarations, except Mixins allow the interfaces of the aggregated class to be included as part of the mixing class. This fact means that it is possible to have multiple versions of the same member name within a mixing class. I propose a simple precedence rule, where the member defined in the class overrides those defined in the aggregated class, and those in the aggregated classes are assigned according to the order they are declared. If this was to take place, a compiler warning message stating "that member X of aggregated class A is taking precedence over that in aggregated class B" should be displayed in the error log. Note: there are probably other things that will need to be considered here ! Conclusion Mixins permit externally declare classes to be used as part of a class, and in so doing provides a real alternative to the Multiple Inheritance option provided for in the C++ language. As such, this relatively insignificant addition to the language should greatly enhance the overall flexibility of the D Programming Language. Comments !
May 04 2004
Please clarify my understanding here. It sounds like mixins, as you are describing them, are (more or less) a generalization of templates.I'm not sure I'd put it like that, but I would certainly agree that they have things in common with templates.If I understand correctly, though, they allow a few more features. But for the moment, bear with me.Will do ..Could I say that the Ranges mixin could also be (hackishly) implemented like this: class Range(C) : C { ...various fields here... } And then the class which mixes it would be defined like this: template ListBase(T,B) { public class List : B // base class , mixes Ranges // Note: do not need to specify mixing class, { } }Yes// Can you use the template shortcut syntax for a typedef? // If so, a typedef would be better hre. template class List(T, B = EmptyBase) : Range(ListBase(T,B)) {}; Obviously, this is a more hackish solution, plus it has more class overhead. Also, in this scenario, Range cannot provide implementations for members of interfaces that List might want to export. But otherwise, does it accomplish nearly the same purpose?Sorry, dude, I just don't get it. Can you explain this example more thoroughly?If so, then I heartily agree with your proposal and will be very excited to get to use it!Ah, a man of great wisdom. ;)Russ Matthew wrote:DTL,Wow, I hadn't realised that this had got so serious! I've been chatting with Walter about a mixins syntax to serve the needs ofasbut had (carelessly / selfishly / stupidly / ...) not put it up on the group,fields -I didn't have time for a debate (which I still don't). Roughly, here's my proposal, which, at first glance, appears to be quite a different kettle of fish to what you're talking about: // - Mixins define class/instance methods. // - Mixins do not define *any* instance fields. (Not sure about staticthemwhat do you think?) // - Mixin methods are added into the mixing class as if the user had typedmixin // - Mixins have *no* polymorphic aspects whatsoever. Two classes that eachthat// the same mixin are nonetheless completely unrelated // - Mixin methods may "become" polymorphic with respect to any interface(s)thatthe mixing class is "implement"ing // - If the mixing class already contains a method of the same signature,gestalt,"overrides" - prevents incorporation - of that mixin method. Syntax: mixin Ranges(C) // C is the mixing class. { private: typedef C.value_type value_type; // A convenience for the mixin implementation, and also a constraint on C typedef C.index_type index_type; // A convenience for the mixin implementation, and also a constraint on C public: boolean contains(value_type comperand) { foreach(value_type v; cast(C)(this)) // How to get to the real,mixingentity. foreach acts as a constraint on C { if(v == comperand) { return cast(boolean)(true); } } return cast(boolean)(false); } . . . } And is used as follows (as in the DTL classes, which require only that theitclass has value_type and index_type member types, and be freachable): template List(T, B = EmptyBase) { public class List : B // base class , mixes Ranges // Note: do not need to specify mixing class, sincemixingcannot be ambiguous. { } } Note that a mixin could also be a template, but needn't be. In a sense, it's already a template, as it's parameterised by one (and only one) type, itsminorclass. Clearly, there are some differences between your proposal and mine: minor:mixingissue, and will be whatever Walter deems most unambiguous and easy to parse major: - you allow for mixins to provide fields - you allow mixins to introduce a different polymorphic nature to theiraclass - you allow mixins to have constructors, which I do not I disagree with all of these, since it seems that your mixin design is almostashalfway house between SI and MI and, although I understand the motivation, I think we'll be in murky territory. Of course, my perspective may well be covered by my needs. ;) Matthew "fred" <info fleet-manage.com> wrote in message news:c6s9ck$7go$1 digitaldaemon.com... I would like to proposed the following specification for Mixins be includedmixingpart of Version 1.0 D Programming Language specification. All comments are welcomed. MIXINS SPECIFICATION Version 0.1 Introduction What are mixins ? A mixin is a class-like entity whose methods/fields are mixed-in to theAggregationclass just as if the author of that class had written them manually. As Matthew so neatly put it (see http://www.digitalmars.com/drn-bin/wwwnews?D/28348 ) Why do we need them ? The rational for Mixins is quite compelling... One of the greatest shortcomings of the C++ language from a Object Oriented perspective, is that there is no language support for Aggregated Objects. As such,mechanism ashas to be performed programatically, often (incorrectly) using the inheritancebetweena coding shortcut. By including language support we provide a direct correlationasOOD using modeling techniques like UML, and OOP. Background Please read the following; http://www.digitalmars.com/drn-bin/wwwnews?D/28455 http://www.digitalmars.com/drn-bin/wwwnews?D/28511 http://www.digitalmars.com/drn-bin/wwwnews?D/28553 Lexicaldeclarations,well as Syntax There are a number of syntax alternatives that could be incorporated. Alternative A: class <identifier> [: <inherited-class>] For example; class Lamp : Light { this() { super(); cBody(); // Body construction cGlobe(); // Globe construction cPowerCord(); // PowerCord construction cSwitch(cGlobe,cPowerCord); // Switch construction } }; Alternative B: class <identifier> [: <inherited-class>] [, <aggregated-class> <local-identifier>]*] For example; class Lamp : Light , Switch cSwitch , Globe cGlobe , PowerCord cPowerCord { this() { super(); cBody(); // Body construction cGlobe(); // Globe construction cPowerCord(); // PowerCord construction cSwitch(cGlobe,cPowerCord); // Switch construction } }; Semantics The rules for Mixin variables should be the same as class membertheexcept Mixins allow the interfaces of the aggregated class to be included as part ofmembermixing class. This fact means that it is possible to have multiple versions of the sameassignedname within a mixing class. I propose a simple precedence rule, where the member defined in the class overrides those defined in the aggregated class, and those in the aggregated classes areaggregatedaccording to the order they are declared. If this was to take place, a compiler warning message stating "that member X of aggregated class A is taking precedence over that inin soclass B" should be displayed in the error log. Note: there are probably other things that will need to be considered here ! Conclusion Mixins permit externally declare classes to be used as part of a class, anddoing provides a real alternative to the Multiple Inheritance option provided for in the C++ language. As such, this relatively insignificant addition to the language should greatly enhance the overall flexibility of the D Programming Language. Comments !
May 04 2004
Matthew wrote:What I was trying to illustrate is that you can define a template which adds member functions to an existing class, which is sort of like a mixin. However, I like your mixin syntax because 1) Looks cleaner 2) You only declare 1 class, rather than 3 (List rather than List->Range(ListBase)->ListBase) 3) In your mixin definition, you can have List implement an interface which includes some functions from List and some from Range. This is not possible with the template solution.Could I say that the Ranges mixin could also be (hackishly) implemented like this: class Range(C) : C { ...various fields here... } And then the class which mixes it would be defined like this: template ListBase(T,B) { public class List : B // base class , mixes Ranges // Note: do not need to specify mixing class, { } }Yes// Can you use the template shortcut syntax for a typedef? // If so, a typedef would be better hre. template class List(T, B = EmptyBase) : Range(ListBase(T,B)) {}; Obviously, this is a more hackish solution, plus it has more class overhead. Also, in this scenario, Range cannot provide implementations for members of interfaces that List might want to export. But otherwise, does it accomplish nearly the same purpose?Sorry, dude, I just don't get it. Can you explain this example more thoroughly?
May 04 2004
"Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message news:c79osk$2ggk$1 digitaldaemon.com...Matthew wrote:thoroughly?Could I say that the Ranges mixin could also be (hackishly) implemented like this: class Range(C) : C { ...various fields here... } And then the class which mixes it would be defined like this: template ListBase(T,B) { public class List : B // base class , mixes Ranges // Note: do not need to specify mixing class, { } }Yes// Can you use the template shortcut syntax for a typedef? // If so, a typedef would be better hre. template class List(T, B = EmptyBase) : Range(ListBase(T,B)) {}; Obviously, this is a more hackish solution, plus it has more class overhead. Also, in this scenario, Range cannot provide implementations for members of interfaces that List might want to export. But otherwise, does it accomplish nearly the same purpose?Sorry, dude, I just don't get it. Can you explain this example moreWhat I was trying to illustrate is that you can define a template which adds member functions to an existing class, which is sort of like a mixin. However, I like your mixin syntax because 1) Looks cleaner 2) You only declare 1 class, rather than 3 (List rather than List->Range(ListBase)->ListBase) 3) In your mixin definition, you can have List implement an interface which includes some functions from List and some from Range. This is not possible with the template solution.Yes, I thought about several different ideas before this one just grabbed me by the you-know-whats. I'm having difficulty persuading Walter that it's the one true way, however, so it may not see the real world. We'll just have to see ...
May 04 2004
"Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message news:c79osk$2ggk$1 digitaldaemon.com...Matthew wrote:thoroughly?Could I say that the Ranges mixin could also be (hackishly) implemented like this: class Range(C) : C { ...various fields here... } And then the class which mixes it would be defined like this: template ListBase(T,B) { public class List : B // base class , mixes Ranges // Note: do not need to specify mixing class, { } }Yes// Can you use the template shortcut syntax for a typedef? // If so, a typedef would be better hre. template class List(T, B = EmptyBase) : Range(ListBase(T,B)) {}; Obviously, this is a more hackish solution, plus it has more class overhead. Also, in this scenario, Range cannot provide implementations for members of interfaces that List might want to export. But otherwise, does it accomplish nearly the same purpose?Sorry, dude, I just don't get it. Can you explain this example moreWhat I was trying to illustrate is that you can define a template which adds member functions to an existing class, which is sort of like a mixin. However, I like your mixin syntax because 1) Looks cleaner 2) You only declare 1 class, rather than 3 (List rather than List->Range(ListBase)->ListBase) 3) In your mixin definition, you can have List implement an interface which includes some functions from List and some from Range. This is not possible with the template solution.Mixins can be a different construct, like a struct/class/interface.
May 05 2004