Thread overview | ||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
May 29, 2004 Mixins don't quite cut it... | ||||
---|---|---|---|---|
| ||||
So here I was and though mixins were powerful enough to help me circumvent some of D's other shortcomings. More specifically, I thought it would be possible to make the missing default values for function arguments a little less painful. It seems that I was wrong :(. Or maybe I just didn't use them in the right way (I fully admit that I don't completely understand the import mechanism that is used). Any hints would be appreciated. I tried to use a mixin that implements the "dummy functions" you need if you want to have default values for function arguments. This would be especially useful for interfaces, since otherwise you'd have to write these dummies for each and every implementation of the interface. I also wanted to use a mixin to provide a default implementation for some of the "real" functions of the interface. But this combination seems to be explosive: Here's the code I tried to compile: interface IFoo { void foo(int i); void foo(int i,int j); } template FooDefaults() { void foo(int i) { this.foo(i,0); } } template FooImpl() { void foo(int i,int j) { } } class Foo : IFoo { mixin FooDefaults; mixin FooImpl; } Unfortunately this doesn't compile: mixinbug.d(9): function foo conflicts with FooImpl!().foo at mixinbug.d(17) mixinbug.d(11): function foo (int i) does not match argument types (int,int) mixinbug.d(11): Error: expected 1 arguments, not 2 Why do the two mixins conflict? I sure hope that it is not because they have the same name, because obviously the signature is completely different. This takes a lot of usefulness from the mixins for me. :( Hauke |
May 29, 2004 Re: Mixins don't quite cut it... | ||||
---|---|---|---|---|
| ||||
Posted in reply to Hauke Duden | Think of mixins like imports. Functions imported from different modules do not overload against each other, they conflict. This is what you're seeing here. You can overload a function from one scope into another using an alias: interface IFoo { void foo(int i); void foo(int i,int j); } template FooDefaults() { void foo(int i) { this.foo(i,0); } } template FooImpl() { void foo(int i,int j) { } } class Foo : IFoo { mixin FooDefaults F1; alias F1.foo foo; mixin FooImpl F2; alias F2.foo foo; } |
May 29, 2004 Re: Mixins don't quite cut it... | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | Walter wrote:
> Think of mixins like imports. Functions imported from different modules do
> not overload against each other, they conflict. This is what you're seeing
> here. You can overload a function from one scope into another using an
> alias:
Hmmm. Ok, now I understand why this happens. I remember trying to persuade you to change this shortcoming for modules a while back ;). Unfortunately the alias workaround isn't much use to me since that would mean I'd still have to write one statement per dummy function :(.
I don't know what it is with D and me. I like the overall concepts a lot but every time I think I should give it a new chance and try to implement something I end up running against another wall in the language design. And to make it worse, it is always a "small" design decision. For example, I like the idea of modules, but D becomes unusable for big projects because a module has to be in a single file. I also like mixins but you cannot use them to "mix" yourself an implementation for an interface. I like the fact that it has operator overloading, but oh, the operators for a class all have to be in the same module, making it impossible to add support for new "argument types" of stream classes. I like that it has a bool type but unfortunately and in contrast to one of the goals of this type the bool in D is actually slower than an int and it can be implicitly converted to integers.
It seems that my way of programming (often library development with interfaces for abstraction from the implementation, plus lots of default function arguments) is just not compatible with D.
At least not the D that we see now. You keep making it better, but I doubt that I'll switch before at least some of the remaining warts are removed. Right now C++ is still better for most of the things I do.
Hauke
|
May 29, 2004 Re: Mixins don't quite cut it... | ||||
---|---|---|---|---|
| ||||
Posted in reply to Hauke Duden |
> I also like mixins but you cannot use them to "mix" yourself an implementation for an interface.
Can you explain this more? Is is the overloading? The following example
seems to work fine:
interface A { void a(); }
template B() { void a(){printf("B.a\n");} }
class C : A { mixin B; }
int main() { C c = new C; c.a(); return 0;}
|
May 29, 2004 Re: Mixins don't quite cut it... | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ben Hinkle | Ben Hinkle wrote:
>>I also like mixins but you cannot use them to "mix" yourself an
>>implementation for an interface.
>
>
> Can you explain this more? Is is the overloading? The following example
> seems to work fine:
> interface A { void a(); }
> template B() { void a(){printf("B.a\n");} }
> class C : A { mixin B; }
> int main() { C c = new C; c.a(); return 0;}
>
>
The problem I'm having is that I would like to have one mixin with dummy functions that emulate default values (because these dummies are always the same for all implementations) and another two or more mixins that provide different default implementations for the functions that provide the real functionality.
But since the dummy functions have the same name (but a different signature) as the functions in the implementation mixins these two mixins cannot be mixed into the same class.
Realworld use: I'd like to provide "building blocks" for interface implementations that allow the implementing class to select alternative partial implementations with different properties and mix them all together to form the full implementation.
Here's an example:
interface IFoo
{
void foo(int i);
void foo(int i,int j);
}
template FooDefaults()
{
void foo(int i)
{
this.foo(i,0); //always the same for all impls
}
}
template FooFastImpl()
{
void foo(int i,int j)
{
//fast implementation with high memory cost
}
}
template FooSmallImpl()
{
void foo(int i,int j)
{
//slow implementation that needs little memory
}
}
class MyFoo : IFoo
{
mixin FooDefaults; //always the same
mixin FooFastImpl; //we want the fast alternative
}
The problem stems from the fact that FooDefaults defines dummies for almost all function names in IFoo. So this makes it impossible to use a mixin to implement the real functions.
Of course, this problem wouldn't occur in this particular case if D would support default values for function arguments. It is a good example how the need to "hack" to get default arguments without copying huge chunks of code causes problems in other areas.
Hauke
|
May 30, 2004 Re: Mixins don't quite cut it... | ||||
---|---|---|---|---|
| ||||
Posted in reply to Hauke Duden | "Hauke Duden" <H.NS.Duden@gmx.net> wrote in message news:c9arki$8uh$1@digitaldaemon.com... > Walter wrote: > > > Think of mixins like imports. Functions imported from different modules do > > not overload against each other, they conflict. This is what you're seeing > > here. You can overload a function from one scope into another using an alias: > > Hmmm. Ok, now I understand why this happens. I remember trying to persuade you to change this shortcoming for modules a while back ;). Unfortunately the alias workaround isn't much use to me since that would mean I'd still have to write one statement per dummy function :(. The reason that mixins are in a separate scope is so that, for more complex mixins, declarations in it can be 'overridden' in the mixed in scope. > I don't know what it is with D and me. I like the overall concepts a lot but every time I think I should give it a new chance and try to implement something I end up running against another wall in the language design. And to make it worse, it is always a "small" design decision. For example, I like the idea of modules, but D becomes unusable for big projects because a module has to be in a single file. Why are large files a problem? And why can't sub-parts of a large module be put in other modules? > I > also like mixins but you cannot use them to "mix" yourself an > implementation for an interface. Actually, you can and it does work. (It didn't work in the original implementation because of a, now fixed, compiler bug.) > I like the fact that it has operator > overloading, but oh, the operators for a class all have to be in the > same module, making it impossible to add support for new "argument > types" of stream classes. Here I'll argue that stream I/O should not use operator overloading. > I like that it has a bool type but > unfortunately and in contrast to one of the goals of this type the bool > in D is actually slower than an int I don't think it is slower. > and it can be implicitly converted > to integers. So it can, too, in C++, so that's not a reason to prefer C++ <g>. > It seems that my way of programming (often library development with interfaces for abstraction from the implementation, plus lots of default function arguments) is just not compatible with D. I'll argue here that I think function overloading is greatly overused, but I know I'm in a minority on that. > At least not the D that we see now. You keep making it better, but I doubt that I'll switch before at least some of the remaining warts are removed. Right now C++ is still better for most of the things I do. > > Hauke |
May 30, 2004 Re: Mixins don't quite cut it... | ||||
---|---|---|---|---|
| ||||
Posted in reply to Hauke Duden | In article <c9b26g$i5u$1@digitaldaemon.com>, Hauke Duden says... > >Ben Hinkle wrote: >... > >The problem stems from the fact that FooDefaults defines dummies for almost all function names in IFoo. So this makes it impossible to use a mixin to implement the real functions. > >Of course, this problem wouldn't occur in this particular case if D would support default values for function arguments. It is a good example how the need to "hack" to get default arguments without copying huge chunks of code causes problems in other areas. > >Hauke > I agree, I too think that "D" should "support default values for function arguments." I use then all the time in Visual Basic 6.0, and I can't image not having them in a new modern programming langauge. Course when I program in "C" I don't have this functionally, but when I recently started taking a closer look at "D", I've been poking around in the "D" html help information looking for this...now I know why I haven't found it yet. :( (I haven't looked at C++ in a long while, but doesn't it have default values for function parameters?) |
May 30, 2004 Re: Mixins don't quite cut it... | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter |
>Why are large files a problem? And why can't sub-parts of a large module be put in other modules?
For one thing the dmd.exe linker will crash if too many symbols or functions are defined in the file... or too many template instantiations (or I presume mixin instantions) are created in a file
|
May 30, 2004 Re: Mixins don't quite cut it... | ||||
---|---|---|---|---|
| ||||
Posted in reply to hellcatv | <hellcatv@hotmail.com> wrote in message news:c9bhcc$16m4$1@digitaldaemon.com... > For one thing the dmd.exe linker will crash if too many symbols or functions are > defined in the file... or too many template instantiations (or I presume mixin > instantions) are created in a file I suspect that something else is going on there... |
May 30, 2004 Re: Mixins don't quite cut it... | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | In article <c9bldd$1bs0$1@digitaldaemon.com>, Walter says... > > ><hellcatv@hotmail.com> wrote in message news:c9bhcc$16m4$1@digitaldaemon.com... >> For one thing the dmd.exe linker will crash if too many symbols or >functions are >> defined in the file... or too many template instantiations (or I presume >mixin >> instantions) are created in a file > >I suspect that something else is going on there... > > well I've tested it with many simple and complex examples: it's not just templates...and they all work using gdc http://graphics.stanford.edu/~danielrh/vec.d http://graphics.stanford.edu/~danielrh/manyfuncs.d http://graphics.stanford.edu/~danielrh/close.d http://graphics.stanford.edu/~danielrh/sclass.d on most of these setting version=DontCrash will cause the linker to succeed by truncating some functions (they're all pretty well empty functions causing these crashes) |
Copyright © 1999-2021 by the D Language Foundation