www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Help with mixins

reply Derek Parnell <derek psych.ward> writes:
I guess I don't really understand the mixin concept after all. Here is the
code example (after cutting it down from a very large source file) that is
giving me grief...

module test;
class Foo
{
    template SetStool(T) { void Setter(T A) { BarStool = A;} }

    real BarStool;
    
    mixin SetStool!(real);           // #1
    mixin SetStool!(float);          // #2 
    
//    void Setter(real A){ BarStool = A; }  // #3
//    void Setter(float A){ BarStool = A; } // #4
        
    this (float A)    { this.Setter( A ); }
    this (real A)     { this.Setter( A ); }

}

The messages I get are ...

test.d(6): function test.Foo.SetStool!(real).Setter conflicts with
test.Foo.SetStool!(float).Setter at test.d(6)
test.d(6): function test.Foo.SetStool!(real).Setter conflicts with
test.Foo.SetStool!(float).Setter at test.d(6)


Now, if I comment out the lines marked #1 and #2, and uncomment #3 and #4,
it compiles fine.

I thought that the two mixin lines (#1, #2) were exactly equivalent to #3
and #4. In other words, by using the mixin, it was as if I'd actually typed
in the text of the template with the appropriate substitutions.

To make matter more confusing, if I just comment out either *one* of the
mixins, it also compiles okay, making it seem as if I'd typed in the Setter
function in full instead of the mixin.

Can somebody explain to me where my understanding is off track?

-- 
Derek
Melbourne, Australia
18/02/2005 2:30:28 PM
Feb 17 2005
parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Fri, 18 Feb 2005 14:30:32 +1100, Derek Parnell <derek psych.ward> wrote:
 I guess I don't really understand the mixin concept after all. Here is  
 the
 code example (after cutting it down from a very large source file) that  
 is
 giving me grief...

 module test;
 class Foo
 {
     template SetStool(T) { void Setter(T A) { BarStool = A;} }

     real BarStool;
    mixin SetStool!(real);           // #1
     mixin SetStool!(float);          // #2
 //    void Setter(real A){ BarStool = A; }  // #3
 //    void Setter(float A){ BarStool = A; } // #4
    this (float A)    { this.Setter( A ); }
     this (real A)     { this.Setter( A ); }

 }

 The messages I get are ...

 test.d(6): function test.Foo.SetStool!(real).Setter conflicts with
 test.Foo.SetStool!(float).Setter at test.d(6)
 test.d(6): function test.Foo.SetStool!(real).Setter conflicts with
 test.Foo.SetStool!(float).Setter at test.d(6)


 Now, if I comment out the lines marked #1 and #2, and uncomment #3 and  
 #4,
 it compiles fine.

 I thought that the two mixin lines (#1, #2) were exactly equivalent to #3
 and #4. In other words, by using the mixin, it was as if I'd actually  
 typed
 in the text of the template with the appropriate substitutions.

 To make matter more confusing, if I just comment out either *one* of the
 mixins, it also compiles okay, making it seem as if I'd typed in the  
 Setter
 function in full instead of the mixin.

 Can somebody explain to me where my understanding is off track?

I'm not sure how much this helps, but it works if you do this... class Foo { template SetStool(T) { void Setter(T A) { BarStool = A;} } real BarStool; mixin SetStool!(real) mr; // #1 alias mr.Setter Setter; mixin SetStool!(float) mf; // #2 alias mf.Setter Setter; // void Setter(real A){ BarStool = A; } // #3 // void Setter(float A){ BarStool = A; } // #4 this (float A) { this.Setter( A ); } this (real A) { this.Setter( A ); } } void main() { } It might have something to do with the fact that "A mixin has its own scope"? Regan
Feb 17 2005
next sibling parent reply Derek Parnell <derek psych.ward> writes:
On Fri, 18 Feb 2005 17:17:53 +1300, Regan Heath wrote:

 On Fri, 18 Feb 2005 14:30:32 +1100, Derek Parnell <derek psych.ward> wrote:
 I guess I don't really understand the mixin concept after all. Here is  
 the
 code example (after cutting it down from a very large source file) that  
 is
 giving me grief...

 module test;
 class Foo
 {
     template SetStool(T) { void Setter(T A) { BarStool = A;} }

     real BarStool;
    mixin SetStool!(real);           // #1
     mixin SetStool!(float);          // #2
 //    void Setter(real A){ BarStool = A; }  // #3
 //    void Setter(float A){ BarStool = A; } // #4
    this (float A)    { this.Setter( A ); }
     this (real A)     { this.Setter( A ); }

 }

 The messages I get are ...

 test.d(6): function test.Foo.SetStool!(real).Setter conflicts with
 test.Foo.SetStool!(float).Setter at test.d(6)
 test.d(6): function test.Foo.SetStool!(real).Setter conflicts with
 test.Foo.SetStool!(float).Setter at test.d(6)


 Now, if I comment out the lines marked #1 and #2, and uncomment #3 and  
 #4,
 it compiles fine.

 I thought that the two mixin lines (#1, #2) were exactly equivalent to #3
 and #4. In other words, by using the mixin, it was as if I'd actually  
 typed
 in the text of the template with the appropriate substitutions.

 To make matter more confusing, if I just comment out either *one* of the
 mixins, it also compiles okay, making it seem as if I'd typed in the  
 Setter
 function in full instead of the mixin.

 Can somebody explain to me where my understanding is off track?

I'm not sure how much this helps, but it works if you do this... class Foo { template SetStool(T) { void Setter(T A) { BarStool = A;} } real BarStool; mixin SetStool!(real) mr; // #1 alias mr.Setter Setter; mixin SetStool!(float) mf; // #2 alias mf.Setter Setter; // void Setter(real A){ BarStool = A; } // #3 // void Setter(float A){ BarStool = A; } // #4 this (float A) { this.Setter( A ); } this (real A) { this.Setter( A ); } } void main() { } It might have something to do with the fact that "A mixin has its own scope"?

Thanks for the hint. Now I read the docs with this fresh perspective, I suspect its the rule ... "If two different mixins are put in the same scope, and each define a declaration with the same name, there is an ambiguity error when the declaration is referenced" coming in to play. Up until now, I read this as "two different mixin _templates_" but it seems that it literally means two "mixin" statements regardless of the template name they are mixing in. Well, I was hoping to reduce the amount of typing I had to do but as the mixin solution involves more typing than copy-paste solution, I guess I leave mixins for another day. -- Derek Melbourne, Australia 18/02/2005 3:37:01 PM
Feb 17 2005
parent Russ Lewis <spamhole-2001-07-16 deming-os.org> writes:
 Well, I was hoping to reduce the amount of typing I had to do but as the
 mixin solution involves more typing than copy-paste solution, I guess I
 leave mixins for another day.

It occurs to me that maybe you should make a mixin which includes both of the overloaded functions. Then you only have to use one mixin statement, and the alias is not required.
Feb 18 2005
prev sibling parent reply Derek Parnell <derek psych.ward> writes:
On Fri, 18 Feb 2005 17:17:53 +1300, Regan Heath wrote:

 On Fri, 18 Feb 2005 14:30:32 +1100, Derek Parnell <derek psych.ward> wrote:
 I guess I don't really understand the mixin concept after all. Here is  
 the
 code example (after cutting it down from a very large source file) that  
 is
 giving me grief...

 module test;
 class Foo
 {
     template SetStool(T) { void Setter(T A) { BarStool = A;} }

     real BarStool;
    mixin SetStool!(real);           // #1
     mixin SetStool!(float);          // #2
 //    void Setter(real A){ BarStool = A; }  // #3
 //    void Setter(float A){ BarStool = A; } // #4
    this (float A)    { this.Setter( A ); }
     this (real A)     { this.Setter( A ); }

 }

 The messages I get are ...

 test.d(6): function test.Foo.SetStool!(real).Setter conflicts with
 test.Foo.SetStool!(float).Setter at test.d(6)
 test.d(6): function test.Foo.SetStool!(real).Setter conflicts with
 test.Foo.SetStool!(float).Setter at test.d(6)


 Now, if I comment out the lines marked #1 and #2, and uncomment #3 and  
 #4,
 it compiles fine.

 I thought that the two mixin lines (#1, #2) were exactly equivalent to #3
 and #4. In other words, by using the mixin, it was as if I'd actually  
 typed
 in the text of the template with the appropriate substitutions.

 To make matter more confusing, if I just comment out either *one* of the
 mixins, it also compiles okay, making it seem as if I'd typed in the  
 Setter
 function in full instead of the mixin.

 Can somebody explain to me where my understanding is off track?

I'm not sure how much this helps, but it works if you do this... class Foo { template SetStool(T) { void Setter(T A) { BarStool = A;} } real BarStool; mixin SetStool!(real) mr; // #1 alias mr.Setter Setter; mixin SetStool!(float) mf; // #2 alias mf.Setter Setter; // void Setter(real A){ BarStool = A; } // #3 // void Setter(float A){ BarStool = A; } // #4 this (float A) { this.Setter( A ); } this (real A) { this.Setter( A ); } } void main() { } It might have something to do with the fact that "A mixin has its own scope"? Regan

BTW, it would be nice if we could do ... alias mixin SetStool!(real).Setter Setter; instead of having to invent a symbol name just for this purpose. -- Derek Melbourne, Australia 18/02/2005 3:50:44 PM
Feb 17 2005
parent reply Ben Hinkle <Ben_member pathlink.com> writes:
BTW, it would be nice if we could do ...

      alias mixin SetStool!(real).Setter Setter;

instead of having to invent a symbol name just for this purpose.

This worked for me: alias SetStool!(float).Setter Setter; alias SetStool!(real).Setter Setter;
Feb 18 2005
parent reply Derek <derek psych.ward> writes:
On Fri, 18 Feb 2005 13:18:12 +0000 (UTC), Ben Hinkle wrote:

BTW, it would be nice if we could do ...

      alias mixin SetStool!(real).Setter Setter;

instead of having to invent a symbol name just for this purpose.

This worked for me: alias SetStool!(float).Setter Setter; alias SetStool!(real).Setter Setter;

Thanks. I was so fixated on 'mixin' that I forgot using it a template ;-) -- Derek Melbourne, Australia
Feb 18 2005
parent "Ben Hinkle" <bhinkle mathworks.com> writes:
"Derek" <derek psych.ward> wrote in message 
news:1hqc25fq33yw9.yjfpno4bcjj9.dlg 40tude.net...
 On Fri, 18 Feb 2005 13:18:12 +0000 (UTC), Ben Hinkle wrote:

BTW, it would be nice if we could do ...

      alias mixin SetStool!(real).Setter Setter;

instead of having to invent a symbol name just for this purpose.

This worked for me: alias SetStool!(float).Setter Setter; alias SetStool!(real).Setter Setter;

Thanks. I was so fixated on 'mixin' that I forgot using it a template ;-)

I was actually surprised the mixin-less version worked. I don't think Setter becomes a member function without using a mixin so I'm not exactly sure what state Setter is in. Some experiments with subclassing should flush out any bugs if there are compiler bugs in there.
Feb 18 2005