digitalmars.D - Quirky mixins
- mattcbro earthlink.net (64/64) May 15 2005 As a new D programmer I embarked on the design of a fairly complex
- Thomas Kuehne (38/57) May 19 2005 -----BEGIN PGP SIGNED MESSAGE-----
- Thomas Kuehne (11/46) May 19 2005 -----BEGIN PGP SIGNED MESSAGE-----
As a new D programmer I embarked on the design of a fairly complex data structure (some new set algorithms I developed). I ran into a fairly steep learning curve using mixins. I had originally wanted to reuse as much code as possible, but I'm not sure that the complex restrictions of mixins and to a lesser extent templates made this worthwhile. Here are some of the restrictions that tripped me up, that I somehow failed to extract from the documentation. 1) templates and hence mixins can only define declarations within their scope. This means that int k = func(g) ; is OK but k = func(g) ; is not, even though k is defined within the body prior to where the mixin is instantiated. 2) Code that is not declarative (e.g. if or switch statements) must appear inside a function or class definition within a template. 3) template specialization can not use arguments passed into functions or class constructors (even if the functions are called with constants that are known at compile time) e.g this won't work template Foo(int bar: 1) { } class Sup { this(int special) { Foo!(special) ; } } 4) There are still a few quirks or perhaps bugs in the compiler. Consider the following code: template addit(int one: 1) { double lhs = y + 1.0 ; } template addit(int zero: 0) { double lhs = y + 0.0 ; } template Foo(int isone) { /* comment out the Foo function below and this will compile */ bool Foo() { return(false) ; } mixin addit!(isone) ; } int main(char[][] args) { double y = 0.0 ; mixin Foo!(0) f0 ; mixin Foo!(1) f1 ; printf("lhs: %g\n", f0.lhs) ; printf("lhs: %g\n", f1.lhs) ; return(0) ; } The compiler returns the error: mixintest.d(26): mixin Foo!(1) f1 Foo is not a template mixintest.d(28): undefined identifier mixin Foo!(1) f1.lhs mixintest.d(28): voids have no value mixintest.d(28): void has no value If the Foo function is commented out there is no problem. This may be due to some kind of interaction with the implicit template property concept. However this template has more than 1 member (Foo and lhs). " I am the way and the truth and the life. No one comes to the Father except through me." Jesus in -John 14
May 15 2005
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 mattcbro earthlink.net schrieb am Mon, 16 May 2005 03:05:23 +0000 (UTC):As a new D programmer I embarked on the design of a fairly complex data structure (some new set algorithms I developed). I ran into a fairly steep learning curve using mixins. I had originally wanted to reuse as much code as possible, but I'm not sure that the complex restrictions of mixins and to a lesser extent templates made this worthwhile. Here are some of the restrictions that tripped me up, that I somehow failed to extract from the documentation. 1) templates and hence mixins can only define declarations within their scope. This means that int k = func(g) ; is OK but k = func(g) ; is not, even though k is defined within the body prior to where the mixin is instantiated. 2) Code that is not declarative (e.g. if or switch statements) must appear inside a function or class definition within a template.Disclamer: I don't know what kind of structure you are working with. Most of the time nested functions can do the job: template Tmpl(T){ static T diff(T a, T b){ return (a<b) ? (b-a) : (a-b); } } void blah(){ int a; mixin Tmpl!(typeof(a)); .... a = diff(a, a*2); .... }3) template specialization can not use arguments passed into functions or class constructors (even if the functions are called with constants that are known at compile time)The arguments have to be "const". One could argue that the compiler could propagate the const attribute. The first rule set I came up with is quite complex and increases the time required for bug pointing by at least on magnitude. How about the following? template Tmpl(T){ T* buffer; .... } class Foo{ this(int i){ mixin Tmpl!(typeof(i)) tmpl; tmpl.buffer = &i; } } Thomas -----BEGIN PGP SIGNATURE----- iD8DBQFCjODj3w+/yD4P9tIRAlB0AKCOTBZrMfmgRzeo5pj2PZu/hbjSCwCfd5eW sx41UuX5N/Ee4mpb6hJ6amg= =SvH8 -----END PGP SIGNATURE-----
May 19 2005
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 mattcbro earthlink.net schrieb am Mon, 16 May 2005 03:05:23 +0000 (UTC): <snip>4) There are still a few quirks or perhaps bugs in the compiler. Consider the following code: template addit(int one: 1) { double lhs = y + 1.0 ; } template addit(int zero: 0) { double lhs = y + 0.0 ; } template Foo(int isone) { /* comment out the Foo function below and this will compile */ bool Foo() { return(false) ; } mixin addit!(isone) ; } int main(char[][] args) { double y = 0.0 ; mixin Foo!(0) f0 ; mixin Foo!(1) f1 ; printf("lhs: %g\n", f0.lhs) ; printf("lhs: %g\n", f1.lhs) ; return(0) ; } The compiler returns the error: mixintest.d(26): mixin Foo!(1) f1 Foo is not a template mixintest.d(28): undefined identifier mixin Foo!(1) f1.lhs mixintest.d(28): voids have no value mixintest.d(28): void has no value If the Foo function is commented out there is no problem. This may be due to some kind of interaction with the implicit template property concept. However this template has more than 1 member (Foo and lhs).Please use the digitalmars.D.bugs group to post suspected bugs. Thomas -----BEGIN PGP SIGNATURE----- iD8DBQFCjOL33w+/yD4P9tIRAqPmAJ0RQ4p/R2yHfX6NME2yUzP2374QpACfe2Ce y5G35rbcABxg+IaOLfo8LoM= =IPgt -----END PGP SIGNATURE-----
May 19 2005