digitalmars.D - Mixins don't quite cut it...
- Hauke Duden (46/46) May 29 2004 So here I was and though mixins were powerful enough to help me
- Walter (29/29) May 29 2004 Think of mixins like imports. Functions imported from different modules ...
- Hauke Duden (26/30) May 29 2004 Hmmm. Ok, now I understand why this happens. I remember trying to
- Ben Hinkle (6/8) May 29 2004 Can you explain this more? Is is the overloading? The following example
- Hauke Duden (53/65) May 29 2004 The problem I'm having is that I would like to have one mixin with dummy...
- David L. Davis (8/18) May 29 2004 I agree, I too think that "D" should "support default values for functio...
- J C Calvarese (13/38) May 30 2004 If you're talking about doing something like this...
- Arcane Jill (12/18) May 30 2004 What I don't understand, is this.
- Hauke Duden (8/13) May 30 2004 I completely disagree! Default arguments are even more needed for
- Regan Heath (9/25) May 31 2004 Why not say:
- Hauke Duden (13/44) Jun 01 2004 The overload must not change the default values, otherwise you get lots
- Regan Heath (8/54) Jun 01 2004 You're stating/assuming the default never changes, even in derived
- Andy Friesen (5/10) May 30 2004 I would rather it be illegal to provide defaults on any method that is
- Hauke Duden (17/33) May 30 2004 Just to make sure I understand: you mean the override must not specify
- Andy Friesen (7/23) May 30 2004 My first instinct is to agree that a bit of syntactic salt would be a
- Hauke Duden (20/34) May 30 2004 No, duplication is good if the "other copy" is in a different class.
- Andy Friesen (13/36) May 30 2004 In almost all cases, this would be the direct parent, the uppermost base...
- Hauke Duden (19/61) May 30 2004 How do you come to that conclusion? Inheritance hierarchies can be deep
- Andy Friesen (11/26) May 31 2004 I meant that having such a heirarchy is a bad sign in and of itself, but...
- David L. Davis (52/52) May 30 2004 *) Ben Hinkle: ... The problem stems from the fact that FooDefaults defi...
- Walter (15/49) May 29 2004 do
- hellcatv hotmail.com (3/5) May 29 2004 For one thing the dmd.exe linker will crash if too many symbols or funct...
- Walter (5/8) May 29 2004 functions are
- hellcatv hotmail.com (10/18) May 29 2004 well I've tested it with many simple and complex examples:
- Walter (3/3) May 30 2004 It happens with the linker when there are more than 16,000 fixups in a
- DemmeGod (2/4) May 30 2004 Unless a package access level was added since I last checked, that would
- Helmut Leitner (6/14) May 30 2004 I share your opinion about overused function overloading,
- Walter (5/14) May 30 2004 default
- Hauke Duden (59/116) May 30 2004 Yes, that is a very important feature too. But that doesn't change the
- Walter (31/104) May 30 2004 be
- Hauke Duden (57/149) May 30 2004 The members are not really accessed by all the code, of course. Probably...
- Walter (38/96) May 30 2004 'alias'
- =?iso-8859-1?q?Knud_S=F8rensen?= (7/46) May 30 2004 If not special care at taken the intelligence of a group
- Hauke Duden (7/9) May 30 2004 One of my favorite authors (Terry Pratchett) wrote that
- Hauke Duden (13/30) May 30 2004 Because int and bool are completely different types. True bools prevent
- Walter (5/13) May 30 2004 new
- Ivan Senji (12/128) May 30 2004 This reply will make a lot of people really really happy!
- Kevin Bealer (33/40) Jun 01 2004 Argument Stanzas
- Walter (5/7) Jun 02 2004 where
- Kevin Bealer (43/50) Jun 02 2004 Like I said, just a wild idea, not a feature request. But optional/defa...
- Norbert Nemec (6/20) Jun 02 2004 Before thinking about that too deeply, I would rather go for the full
- Derek Parnell (17/18) May 30 2004 On Sat, 29 May 2004 16:58:52 -0700, Walter wrote:
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
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
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
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
Ben Hinkle wrote: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. HaukeI 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
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. HaukeI 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 29 2004
David L. Davis wrote:In article <c9b26g$i5u$1 digitaldaemon.com>, Hauke Duden says...If you're talking about doing something like this... void foo(int x, int y = 3) { ... } You can emulate it with something like this... void foo(int x, int y) { ... } void foo(int x) { foo(x, 3); } I'd prefer to do it directly, too, but Walter has some concerns. I've collected some previous threads here (in case you want to review the previous discussions): http://www.wikiservice.at/d/wiki.cgi?FeatureRequestList/DefaultArguments -- Justin (a/k/a jcc7) http://jcc_7.tripod.com/d/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. HaukeI 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
In article <c9d89g$f58$1 digitaldaemon.com>, J C Calvarese says...I'd prefer to do it directly, too, but Walter has some concerns. I've collected some previous threads here (in case you want to review the previous discussions):What I don't understand, is this. If it's "good" for the compiler to allow:void f() { f(0); } void f(int n) { /*stuff*/ }and "bad" for the compiler to allow:void f(int n=0) { /*stuff*/ }Then why can't the compiler simply rewrite the latter as the former before trying to figure out the rules? Just consider it more of that syntactic sugar. I also concur with the person on wiki who suggested that all functions with default arguments be implicitly final. (Or even explicitly, if you really want to make a point). Overloading is common, and default arguments are common, but overloading and default arguments at the same time are rare enough that this is unlikely to be much of a problem. Arcane Jill
May 30 2004
Arcane Jill wrote:I also concur with the person on wiki who suggested that all functions with default arguments be implicitly final. (Or even explicitly, if you really want to make a point). Overloading is common, and default arguments are common, but overloading and default arguments at the same time are rare enough that this is unlikely to be much of a problem.I completely disagree! Default arguments are even more needed for interfaces than for normal classes, since without them EVERY implementation has to include all the dummy functions. A better rule would be that all overloads simply have to define the same default arguments. The default shouldn't change depending on the context in which the function is called anyway. Hauke
May 30 2004
On Sun, 30 May 2004 20:54:10 +0200, Hauke Duden <H.NS.Duden gmx.net> wrote:Arcane Jill wrote:Why not say: "Overloads must specify a default value for every parameter in the overloaded function(s) that have default value(s)." So if you have foo(int a=0, int b) and foo(int a, int b=6) you must specify defaults for both a and b i.e. foo(int a=1, int b=2) Regan. -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/I also concur with the person on wiki who suggested that all functions with default arguments be implicitly final. (Or even explicitly, if you really want to make a point). Overloading is common, and default arguments are common, but overloading and default arguments at the same time are rare enough that this is unlikely to be much of a problem.I completely disagree! Default arguments are even more needed for interfaces than for normal classes, since without them EVERY implementation has to include all the dummy functions. A better rule would be that all overloads simply have to define the same default arguments. The default shouldn't change depending on the context in which the function is called anyway.
May 31 2004
Regan Heath wrote:On Sun, 30 May 2004 20:54:10 +0200, Hauke Duden <H.NS.Duden gmx.net> wrote:The overload must not change the default values, otherwise you get lots of weirdness, like the function call behaving differently depending on the type of the object reference (i.e. a call with a base class reference would have different defaults than the same call with a subclass reference). It is also useless because defaults are not arbitrary values, so they don't change. I'm more and more convinced that the best solution is to have the simple rule: All overloads must specify exactly the same defaults as the original method. That way all cases are handled well, there is no ambiguity, it is easy to read and easy to understand. HaukeArcane Jill wrote:Why not say: "Overloads must specify a default value for every parameter in the overloaded function(s) that have default value(s)." So if you have foo(int a=0, int b) and foo(int a, int b=6) you must specify defaults for both a and b i.e. foo(int a=1, int b=2)I also concur with the person on wiki who suggested that all functions with default arguments be implicitly final. (Or even explicitly, if you really want to make a point). Overloading is common, and default arguments are common, but overloading and default arguments at the same time are rare enough that this is unlikely to be much of a problem.I completely disagree! Default arguments are even more needed for interfaces than for normal classes, since without them EVERY implementation has to include all the dummy functions. A better rule would be that all overloads simply have to define the same default arguments. The default shouldn't change depending on the context in which the function is called anyway.
Jun 01 2004
On Tue, 01 Jun 2004 11:01:23 +0200, Hauke Duden <H.NS.Duden gmx.net> wrote:Regan Heath wrote:You're stating/assuming the default never changes, even in derived classes. Why does that have to be the case? What is wrong with have a default initial size in a storage class, deriving a specialised version of that storage class from it and setting a different default initial size?On Sun, 30 May 2004 20:54:10 +0200, Hauke Duden <H.NS.Duden gmx.net> wrote:The overload must not change the default values, otherwise you get lots of weirdness, like the function call behaving differently depending on the type of the object reference (i.e. a call with a base class reference would have different defaults than the same call with a subclass reference). It is also useless because defaults are not arbitrary values, so they don't change.Arcane Jill wrote:Why not say: "Overloads must specify a default value for every parameter in the overloaded function(s) that have default value(s)." So if you have foo(int a=0, int b) and foo(int a, int b=6) you must specify defaults for both a and b i.e. foo(int a=1, int b=2)I also concur with the person on wiki who suggested that all functions with default arguments be implicitly final. (Or even explicitly, if you really want to make a point). Overloading is common, and default arguments are common, but overloading and default arguments at the same time are rare enough that this is unlikely to be much of a problem.I completely disagree! Default arguments are even more needed for interfaces than for normal classes, since without them EVERY implementation has to include all the dummy functions. A better rule would be that all overloads simply have to define the same default arguments. The default shouldn't change depending on the context in which the function is called anyway.I'm more and more convinced that the best solution is to have the simple rule: All overloads must specify exactly the same defaults as the original method. That way all cases are handled well, there is no ambiguity, it is easy to read and easy to understand. Hauke-- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
Jun 01 2004
Arcane Jill wrote:I also concur with the person on wiki who suggested that all functions with default arguments be implicitly final. (Or even explicitly, if you really want to make a point). Overloading is common, and default arguments are common, but overloading and default arguments at the same time are rare enough that this is unlikely to be much of a problem.I would rather it be illegal to provide defaults on any method that is an override, including interface implementations. (by extension, then, interfaces would be allowed to provide defaults) -- andy
May 30 2004
Andy Friesen wrote:Arcane Jill wrote:Just to make sure I understand: you mean the override must not specify defaults because it will implicitly inherit the ones from the original defintion, correct? I would prefer that the defaults have to be explicit, but always the same as the original ones. That way they can be seen without having to look at any base classes. Also, your system has another problem: what if two interfaces define the same function with different defaults? Then there are two "original" definitions, so this needs to be handled specifically. If you require the overloads to have the same defaults then this case is automatically handled, because no overload can have the same defaults as both the methods it overrides. I.e. it is not possible to implement both interfaces in the same object, which is the only solution I can see. It would be the same as if the interfaces defined methods with the same parameter lists but different return values. HaukeI also concur with the person on wiki who suggested that all functions with default arguments be implicitly final. (Or even explicitly, if you really want to make a point). Overloading is common, and default arguments are common, but overloading and default arguments at the same time are rare enough that this is unlikely to be much of a problem.I would rather it be illegal to provide defaults on any method that is an override, including interface implementations. (by extension, then, interfaces would be allowed to provide defaults)
May 30 2004
Hauke Duden wrote:Andy Friesen wrote:Exactly.I would rather it be illegal to provide defaults on any method that is an override, including interface implementations. (by extension, then, interfaces would be allowed to provide defaults)Just to make sure I understand: you mean the override must not specify defaults because it will implicitly inherit the ones from the original defintion, correct?I would prefer that the defaults have to be explicit, but always the same as the original ones. That way they can be seen without having to look at any base classes.My first instinct is to agree that a bit of syntactic salt would be a good thing, but, on second thought, it means duplication, which is Very Bad.Also, your system has another problem: what if two interfaces define the same function with different defaults? Then there are two "original" definitions, so this needs to be handled specifically.In such a case, the two functions are distinct, even if they happen to have the same name. There is no conflict. -- andy
May 30 2004
Andy Friesen wrote: >> I would prefer that the defaults have to be explicit, but always theNo, duplication is good if the "other copy" is in a different class. Otherwise, when you see a method foo(int a,int b) in a class, how do you know how you can call it? Is there a default value for a or b? What is it? To find out you'd have to look in all base classes and see if they contain a function foo(int,int). That is what I consider bad.same as the original ones. That way they can be seen without having to look at any base classes.My first instinct is to agree that a bit of syntactic salt would be a good thing, but, on second thought, it means duplication, which is Very Bad.Urgh!!! So what happens if you have foo(int a=0) and foo(int a=5)? Which default value is chosen when someone calls foo()? And how'd you overload these two distinct functions without duplicating the default values? How do you indicate which one to overload? I don't think this can work. I think the only sensible solution is that different defaults are a conflict and that all overloads must specify the same defaults as the base class function they are overloading. It is easy to read, immediately understandable, typos are caught at compile time and function calling is unambiguous. HaukeAlso, your system has another problem: what if two interfaces define the same function with different defaults? Then there are two "original" definitions, so this needs to be handled specifically.In such a case, the two functions are distinct, even if they happen to have the same name. There is no conflict.
May 30 2004
Hauke Duden wrote:... when you see a method foo(int a,int b) in a class, how do you know how you can call it? Is there a default value for a or b? What is it? To find out you'd have to look in all base classes and see if they contain a function foo(int,int). That is what I consider bad.In almost all cases, this would be the direct parent, the uppermost base class, or an interface. Hopefully, it would almost always be an interface or abstract class. (implementation inheritance is scary)Waaait a second. I had no idea that two interfaces could 'overlap' in this way. Since foo() is the same method for both interfaces, the defaults should necessarily coincide. If they don't, it's probably a bug anyway. (even if it isn't, it sure looks like one)Urgh!!! So what happens if you have foo(int a=0) and foo(int a=5)? Which default value is chosen when someone calls foo()?Also, your system has another problem: what if two interfaces define the same function with different defaults? Then there are two "original" definitions, so this needs to be handled specifically.In such a case, the two functions are distinct, even if they happen to have the same name. There is no conflict.I think the only sensible solution is that different defaults are a conflict and that all overloads must specify the same defaults as the base class function they are overloading. It is easy to read, immediately understandable, typos are caught at compile time and function calling is unambiguous.It has real potential to be a maintenance nightmare if a default has to change, however. I think I see why Walter wanted to leave these out. :) -- andy
May 30 2004
Andy Friesen wrote:Hauke Duden wrote:How do you come to that conclusion? Inheritance hierarchies can be deep and new functions can be added at any level. Classes can also implement many interfaces. So you'd potentially have to look at many classes or interfaces!... when you see a method foo(int a,int b) in a class, how do you know how you can call it? Is there a default value for a or b? What is it? To find out you'd have to look in all base classes and see if they contain a function foo(int,int). That is what I consider bad.In almost all cases, this would be the direct parent, the uppermost base class, or an interface.Sure. Otherwise you could never implement an interface that inherits from an interface a base class has already implemented.Waaait a second. I had no idea that two interfaces could 'overlap' in this way.Urgh!!! So what happens if you have foo(int a=0) and foo(int a=5)? Which default value is chosen when someone calls foo()?Also, your system has another problem: what if two interfaces define the same function with different defaults? Then there are two "original" definitions, so this needs to be handled specifically.In such a case, the two functions are distinct, even if they happen to have the same name. There is no conflict.Since foo() is the same method for both interfaces, the defaults should necessarily coincide. If they don't, it's probably a bug anyway. (even if it isn't, it sure looks like one)I agree.Well, I think if you ever need to change a default then it IS already a maintenance nightmare. Because all the calling code will have been written with the old default you'd have to review every piece of code where the function is called to see if it still applies to the new one. Going through all base classes doesn't add much to that. Anyway, in all my years of programming C++, I don't remember ever changing a default value. The default is not any arbitrary value, it is what you need to pass to the function if you don't really want to USE the parameter. That kind of value doesn't change as long as the function's task doesn't change. HaukeI think the only sensible solution is that different defaults are a conflict and that all overloads must specify the same defaults as the base class function they are overloading. It is easy to read, immediately understandable, typos are caught at compile time and function calling is unambiguous.It has real potential to be a maintenance nightmare if a default has to change, however.
May 30 2004
Hauke Duden wrote:Andy Friesen wrote:I meant that having such a heirarchy is a bad sign in and of itself, but I'm not so sure now. I myself tend to avoid implementation inheritance like the plague, leading to relatively flat object heirarchies. It's certainly the most effective way for *me* to think, but I shouldn't be so quick to assume it's the best approach for every problem.In almost all cases, this would be the direct parent, the uppermost base class, or an interface.How do you come to that conclusion? Inheritance hierarchies can be deep and new functions can be added at any level. Classes can also implement many interfaces. So you'd potentially have to look at many classes or interfaces!I think if you ever need to change a default then it IS already a maintenance nightmare. Because all the calling code will have been written with the old default you'd have to review every piece of code where the function is called to see if it still applies to the new one. Going through all base classes doesn't add much to that.Come to think of it, it's no more or less of a hassle than any other change one might make to an interface. blah. All this thinking is leading me back to the conclusion that overloaded methods solve the problem better, if a tad more verbosely. :) -- andy
May 31 2004
*) Ben Hinkle: ... 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. ------------ *) David L. Davis [reply to Ben]: 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?) ------------ *) J C Calvarese [reply to David]: If you're talking about doing something like this... void foo(int x, int y = 3) { ... } You can emulate it with something like this... void foo(int x, int y) { ... } void foo(int x) { foo(x, 3); } I'd prefer to do it directly, too, but Walter has some concerns. I've collected some previous threads here (in case you want to review the previous discussions): http://www.wikiservice.at/d/wiki.cgi?FeatureRequestList/DefaultArguments -- Justin (a/k/a jcc7) http://jcc_7.tripod.com/d/ ------------ J C Calvarese: Thanks for the reply. I'll keep a note of the above emulation approach in mind for current needs, but it does look like "D" will support "default function arguments" directly in some future build. Below is a potion of the thread, title: "Re: Mixins don't quite cut it..." dated: "Sun, 30 May 2004 10:45:08 -0700" where it looks like Walter has been listening to the forum about this issue, and it sounds like to me that he's going to add "default function arguments" to "D!" :)) If this is truly the case, then this is really "Great News!" <g> ----------- <default function arguments portion> Hauke Duden:"I'm talking about DMD 0.91 here. The problem appears when you try to have different mixins that provide functions with the same name but different signatures. Again, the importing algorithm is the culprit. And the reason I wanted to do this is to provide a mixin with the 'dummy' functions you need to write to get default values for function arguments. This is all described in more detail in my another of my posts: http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/2456" Walter [reply to Hauke]:"Seeing the lengths people go to try to emulate default function arguments makes it pretty obvious that I need to add it to the language, I'd underestimated it." </default function arguments portion> -------------
May 30 2004
"Hauke Duden" <H.NS.Duden gmx.net> wrote in message news:c9arki$8uh$1 digitaldaemon.com...Walter wrote:doThink of mixins like imports. Functions imported from different modulesseeingnot overload against each other, they conflict. This is what you'reThe 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.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.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 intI 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 29 2004
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 29 2004
<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 orfunctions aredefined in the file... or too many template instantiations (or I presumemixininstantions) are created in a fileI suspect that something else is going on there...
May 29 2004
In article <c9bldd$1bs0$1 digitaldaemon.com>, Walter says...<hellcatv hotmail.com> wrote in message news:c9bhcc$16m4$1 digitaldaemon.com...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)For one thing the dmd.exe linker will crash if too many symbols orfunctions aredefined in the file... or too many template instantiations (or I presumemixininstantions) are created in a fileI suspect that something else is going on there...
May 29 2004
It happens with the linker when there are more than 16,000 fixups in a single .obj file. Apparently, it's most likely an overflow of a short in the linker.
May 30 2004
Why are large files a problem? And why can't sub-parts of a large module be put in other modules?Unless a package access level was added since I last checked, that would expose subparts that one wouldn't necessarily want exposed.
May 30 2004
Walter wrote:"Hauke Duden" <H.NS.Duden gmx.net> wrote in messageI share your opinion about overused function overloading, but I also share Haukes feelings of running against walls. -- Helmut Leitner leitner hls.via.at Graz, Austria www.hls-software.comIt 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.
May 30 2004
"Helmut Leitner" <helmut.leitner wikiservice.at> wrote in message news:40B98DF6.FEBF47C5 wikiservice.at...Walter wrote:default"Hauke Duden" <H.NS.Duden gmx.net> wrote in messageIt seems that my way of programming (often library development with interfaces for abstraction from the implementation, plus lots ofbut Ifunction arguments) is just not compatible with D.I'll argue here that I think function overloading is greatly overused,Which walls are yours?know I'm in a minority on that.I share your opinion about overused function overloading, but I also share Haukes feelings of running against walls.
May 30 2004
Walter wrote:Yes, that is a very important feature too. But that doesn't change the fact limits of the importing algorithm also limit the usefulness of mixins.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.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 :(.There was a big thread about this the other day called "Module with multiple files". The main problem is that when multiple classes need to collaborate with each other, i.e. if they need friend access, then you have to put them into the same file. With some kinds of class libraries that can mean huge files with tens of thousands of lines of code, which is impossible to manage efficiently when you have multiple programmers working on the classes at the same time. A "package" access level would help, as would the ability to split a module into multiple files (for example, the option to use a directory as a module). But the overloading problem also plays into it: if you want to break a module into sub-modules then all overloading functions must be in the same file. This can be counter-intuitive, as it is often more straightforward to put any global functions into the same file as the classes it takes as arguments.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'm talking about DMD 0.91 here. The problem appears when you try to have different mixins that provide functions with the same name but different signatures. Again, the importing algorithm is the culprit. And the reason I wanted to do this is to provide a mixin with the "dummy" functions you need to write to get default values for function arguments. This is all described in more detail in my another of my posts: http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/2456I 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.)It is the same if you use global functions, since they overload in the same way, so this kind of thing: class Stream; void store(Stream s,String x); <other file> void store(Stream s,MyClass c); doesn't work either. Because of this you cannot add support for, for example, storing new types to a stream class without using runtime polymorphy. And that is a problem because D also has structs which cannot implement interfaces, so you cannot add support for "being stored" to any struct whose base class you cannot control.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.You told me yourself. You said you use "int" as the return type for islower and isupper because having ==0, !=0 semantics usually takes two operations less than having ==0,==1 semantics (as you'd have with bool/bit).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 intI don't think it is slower.Yes, but C++ is my current language. Switching languages means a lot of work, so D has to offer compelling advantages. It fails to do so with the bool type.and it can be implicitly converted to integers.So it can, too, in C++, so that's not a reason to prefer C++ <g>.Then you need to ask yourself whether you create the language just for yourself or also for the "majority". It is your decision of course, but if other people use lots of overloading and you want them to use your language ... I want to be honest here: most of the stuff I mentioned here is by itself not enough for me to "condemn" the language. Otherwise I wouldn't be posting here. But it adds up. One of the most important issues for me is still the lack of default values for function arguments. To give you an example, I recently wrote a String interface plus different implementations as a "tryout project" for D. That string interface has 48 "real" methods and 36 dummy methods to implement default values (almost all methods have one or two default arguments). So for each implementation you have to write almost twice as many methods as really necessary. My attempts to work around this limitation with mixins were the reason why I kept bumping into the mixin and overloading problems. HaukeIt 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.
May 30 2004
"Hauke Duden" <H.NS.Duden gmx.net> wrote in message news:c9cguf$2hue$1 digitaldaemon.com...beWhy are large files a problem? And why can't sub-parts of a large moduleI'll go review the thread, but at the moment I have a hard time imagining why members should be private when they need to be accessed by tens of thousands of lines of other code. But the package level access sounds like a good feature to add.put in other modules?There was a big thread about this the other day called "Module with multiple files". The main problem is that when multiple classes need to collaborate with each other, i.e. if they need friend access, then you have to put them into the same file. With some kinds of class libraries that can mean huge files with tens of thousands of lines of code, which is impossible to manage efficiently when you have multiple programmers working on the classes at the same time. A "package" access level would help, as would the ability to split a module into multiple files (for example, the option to use a directory as a module).But the overloading problem also plays into it: if you want to break a module into sub-modules then all overloading functions must be in the same file. This can be counter-intuitive, as it is often more straightforward to put any global functions into the same file as the classes it takes as arguments.One can overload functions from different import scopes using the 'alias' capability. I believe this explicit control over function overloading is better than C++ for handling very large programs - in C++ with its global overloading and ADL one can get really lost as to which functions are 'in play' for overloading.Seeing the lengths people go to try to emulate default function arguments makes it pretty obvious that I need to add it to the language, I'd underestimated it.I'm talking about DMD 0.91 here. The problem appears when you try to have different mixins that provide functions with the same name but different signatures. Again, the importing algorithm is the culprit. And the reason I wanted to do this is to provide a mixin with the "dummy" functions you need to write to get default values for function arguments. This is all described in more detail in my another of my posts: http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/2456I 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.)It is the same if you use global functions, since they overload in the same way, so this kind of thing: class Stream; void store(Stream s,String x); <other file> void store(Stream s,MyClass c); doesn't work either. Because of this you cannot add support for, for example, storing new types to a stream class without using runtime polymorphy. And that is a problem because D also has structs which cannot implement interfaces, so you cannot add support for "being stored" to any struct whose base class you cannot control.There's got to be a better way <g>.bool/bit). That's to create a bool from an int. This overhead isn't there once it is a bool. I don't know of any conceivable implementation of bool (and that includes C++'s bool) that doesn't have this overhead in converting to a bool.You told me yourself. You said you use "int" as the return type for islower and isupper because having ==0, !=0 semantics usually takes two operations less than having ==0,==1 semantics (as you'd have withI 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 intI don't think it is slower.I have been surprised at the amount of controversy over a bool type (Matthew is solidly in your camp on this, too!). I recall many l-o-n-g threads in newsgroups over the semantics of bool to C years ago.Yes, but C++ is my current language. Switching languages means a lot of work, so D has to offer compelling advantages. It fails to do so with the bool type.and it can be implicitly converted to integers.So it can, too, in C++, so that's not a reason to prefer C++ <g>.but II'll argue here that I think function overloading is greatly overused,A good point. But also consider that I wouldn't have created this newsgroup if I wasn't interested in other peoples' views. D has grown and improved a lot based on feedback from the members here. But the risk D runs in trying to please everyone is becoming a mish-mash of conflicting, overlapping features.know I'm in a minority on that.Then you need to ask yourself whether you create the language just for yourself or also for the "majority". It is your decision of course, but if other people use lots of overloading and you want them to use your language ...I want to be honest here: most of the stuff I mentioned here is by itself not enough for me to "condemn" the language. Otherwise I wouldn't be posting here. But it adds up.I appreciate you taking the time to post your thoughts on it here.One of the most important issues for me is still the lack of default values for function arguments. To give you an example, I recently wrote a String interface plus different implementations as a "tryout project" for D. That string interface has 48 "real" methods and 36 dummy methods to implement default values (almost all methods have one or two default arguments). So for each implementation you have to write almost twice as many methods as really necessary. My attempts to work around this limitation with mixins were the reason why I kept bumping into the mixin and overloading problems. Hauke
May 30 2004
Walter wrote:The members are not really accessed by all the code, of course. Probably only in a couple of places. But the classes can each have a few thousand lines and if they need to access each other's private members then they all have to be in the same file. But if you really add package access this problem is solved. :)There was a big thread about this the other day called "Module with multiple files". The main problem is that when multiple classes need to collaborate with each other, i.e. if they need friend access, then you have to put them into the same file. With some kinds of class libraries that can mean huge files with tens of thousands of lines of code, which is impossible to manage efficiently when you have multiple programmers working on the classes at the same time. A "package" access level would help, as would the ability to split a module into multiple files (for example, the option to use a directory as a module).I'll go review the thread, but at the moment I have a hard time imagining why members should be private when they need to be accessed by tens of thousands of lines of other code. But the package level access sounds like a good feature to add.Well, when you use alias you always have to manually "prepare" the aliases for all overloaded functions you want to use. That makes it impossible to use two modules in combination by simply importing them both. Having said that, this really is one of the less important points for me. If the function overloading hadn't played into the mixin stuff I tried to pull off to implement default function arguments I wouldn't have mentioned it. As I said in another post, I usually use lots of interfaces, so runtime polymorphy works well enough for me in most situations.But the overloading problem also plays into it: if you want to break a module into sub-modules then all overloading functions must be in the same file. This can be counter-intuitive, as it is often more straightforward to put any global functions into the same file as the classes it takes as arguments.One can overload functions from different import scopes using the 'alias' capability. I believe this explicit control over function overloading is better than C++ for handling very large programs - in C++ with its global overloading and ADL one can get really lost as to which functions are 'in play' for overloading.Yay! If you do that D will immediately climb a lot higher on my language ranking ladder ;).Seeing the lengths people go to try to emulate default function arguments makes it pretty obvious that I need to add it to the language, I'd underestimated it.I'm talking about DMD 0.91 here. The problem appears when you try to have different mixins that provide functions with the same name but different signatures. Again, the importing algorithm is the culprit. And the reason I wanted to do this is to provide a mixin with the "dummy" functions you need to write to get default values for function arguments. This is all described in more detail in my another of my posts: http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/2456I 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.)If a bool is simply a 32 bit value where 0 means false and !=0 means true then no conversion is necessary. Of course, there is some additional overhead when comparing two bool variables because they could both be true but have different values. But in my experience bool variables are very rarely compared to each other. Most of the time they are set to true or false or their true-ness is checked. There is no additional overhead for this. In fact, I believe such a bool allows the compiler to do additional optimizations, like the one you did manually with "islower". Only when the bool is explicitly converted to an int should the compiler perform the conversion !=0 => 1. I think such a bool as a distinct type without implicit conversions to and from integers would be the best possible way to do it.bool/bit). That's to create a bool from an int. This overhead isn't there once it is a bool. I don't know of any conceivable implementation of bool (and that includes C++'s bool) that doesn't have this overhead in converting to a bool.You told me yourself. You said you use "int" as the return type for islower and isupper because having ==0, !=0 semantics usually takes two operations less than having ==0,==1 semantics (as you'd have withI 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 intI don't think it is slower.So why are you surprised? :) I never encountered any situation where I needed to use a bool as an integer in pure C++ or JAVA code. The only thing that comes close is when interfacing with C code that expects an int instead of a bool. But that is mostly a problem of C++ because it is source code compatible with C. D has the opportunity to break with this, since it only needs binary compatibility with C.I have been surprised at the amount of controversy over a bool type (Matthew is solidly in your camp on this, too!). I recall many l-o-n-g threads in newsgroups over the semantics of bool to C years ago.and it can be implicitly convertedYes, but C++ is my current language. Switching languages means a lot of work, so D has to offer compelling advantages. It fails to do so with the bool type.to integers.So it can, too, in C++, so that's not a reason to prefer C++ <g>.I know and I am constantly surprised when you release a new DMD version and a lot of NG ideas are in there. I also realize that you need to try work through all the suggestions to see which features are REALLY needed by many people. But sometimes it seems that there are lots of people in the NG who all agree that something should be changed and there is no comment from you anywhere to be seen. Which doesn't mean that you don't listen, of course, because a month later this feature may very well be in the language. Or it may not because you have never had a problem with it yourself (see switch). Just to avoid misunderstandings: I believe every language should be designed by a single individual, since the compromises you get with design groups are often worse than the simple bad decisions a single person can make. I think your model of "eaves-dropping emperor" is really one of the better ones. But sometimes I wish you'd at least give some feedback when you have been convinced of something, so that we can stop and do something more productive :). A page of features that are on your todo list for a future version of DMD would be great. Haukebut II'll argue here that I think function overloading is greatly overused,A good point. But also consider that I wouldn't have created this newsgroup if I wasn't interested in other peoples' views. D has grown and improved a lot based on feedback from the members here. But the risk D runs in trying to please everyone is becoming a mish-mash of conflicting, overlapping features.know I'm in a minority on that.Then you need to ask yourself whether you create the language just for yourself or also for the "majority". It is your decision of course, but if other people use lots of overloading and you want them to use your language ...
May 30 2004
"Hauke Duden" <H.NS.Duden gmx.net> wrote in message news:c9d9v1$hdd$1 digitaldaemon.com...Walter wrote:'alias'One can overload functions from different import scopes using theglobalcapability. I believe this explicit control over function overloading is better than C++ for handling very large programs - in C++ with its'inoverloading and ADL one can get really lost as to which functions areboth. No, you just need to do one alias per imported name. Not one for each overload of each function. The alias pulls in all the functions of the same name.play' for overloading.Well, when you use alias you always have to manually "prepare" the aliases for all overloaded functions you want to use. That makes it impossible to use two modules in combination by simply importing themis aThat's to create a bool from an int. This overhead isn't there once itThen just use an int. I just don't see what the problem is.bool. I don't know of any conceivable implementation of bool (and that includes C++'s bool) that doesn't have this overhead in converting to a bool.If a bool is simply a 32 bit value where 0 means false and !=0 means true then no conversion is necessary.But in my experience bool variables are very rarely compared to each other. Most of the time they are set to true or false or their true-ness is checked. There is no additional overhead for this.And there is none in D.In fact, I believe such a bool allows the compiler to do additional optimizations, like the one you did manually with "islower". Only when the bool is explicitly converted to an int should the compiler perform the conversion !=0 => 1. I think such a bool as a distinct type without implicit conversions to and from integers would be the best possible way to do it.It just doesn't set well with me that two values of a type can compare 'equal' yet contain entirely different bit patterns.(MatthewI have been surprised at the amount of controversy over a bool typeI was surprised then, too. It's just much ado over next-to-nothing. (I argue about this with Matthew, too <g>.) One thing that is clear, though, is that there's no agreement at all.is solidly in your camp on this, too!). I recall many l-o-n-g threads in newsgroups over the semantics of bool to C years ago.So why are you surprised? :)I never encountered any situation where I needed to use a bool as an integer in pure C++ or JAVA code. The only thing that comes close is when interfacing with C code that expects an int instead of a bool. But that is mostly a problem of C++ because it is source code compatible with C. D has the opportunity to break with this, since it only needs binary compatibility with C.bool has been added to both C and C++, so if there was an obvious semantic meaning for it, such would have been chosen. But there was no consensus on what the 'obvious' semantics should be. People continue to fruitlessly argue about it. I'd rather move on <g>.newsgroupA good point. But also consider that I wouldn't have created thisaif I wasn't interested in other peoples' views. D has grown and improvedtryinglot based on feedback from the members here. But the risk D runs inThe problem is I'm a thousand or two messages behind in reading the n.g. Even when I do post replies, that frequently inspires a whole ream of new postings. So the more I read and post, the further I get behind. I'm currently trying to wrap up reading the January postings. I'm not complaining, however, since the huge volume of messages is a wonderful sign of the health of the D community!to please everyone is becoming a mish-mash of conflicting, overlapping features.I know and I am constantly surprised when you release a new DMD version and a lot of NG ideas are in there. I also realize that you need to try work through all the suggestions to see which features are REALLY needed by many people. But sometimes it seems that there are lots of people in the NG who all agree that something should be changed and there is no comment from you anywhere to be seen. Which doesn't mean that you don't listen, of course, because a month later this feature may very well be in the language. Or it may not because you have never had a problem with it yourself (see switch).Just to avoid misunderstandings: I believe every language should be designed by a single individual, since the compromises you get with design groups are often worse than the simple bad decisions a single person can make.Design-by-committee suffers from the "vote for my feature and I'll vote for yours" madness. And it still is no guarantee that wretched misfeatures won't get in the language, I submit C++'s 'export' as the canonical example <g>. That said, there is still a time and a place for a standards committee for a language, but that is after it is designed and all major features are in place.I think your model of "eaves-dropping emperor" is really one of the better ones. But sometimes I wish you'd at least give some feedback when you have been convinced of something, so that we can stop and do something more productive :). A page of features that are on your todo list for a future version of DMD would be great.I keep thinking I'm done with 1.0 features <g>.
May 30 2004
If not special care at taken the intelligence of a group is often the average of its members. To solve this I have created what I call an eigenpoll. http://all-technology.com/eigenpolls/ If you like I will make one for D suggestions. KnudnewsgroupA good point. But also consider that I wouldn't have created thisaif I wasn't interested in other peoples' views. D has grown and improvedtryinglot based on feedback from the members here. But the risk D runs inThe problem is I'm a thousand or two messages behind in reading the n.g. Even when I do post replies, that frequently inspires a whole ream of new postings. So the more I read and post, the further I get behind. I'm currently trying to wrap up reading the January postings. I'm not complaining, however, since the huge volume of messages is a wonderful sign of the health of the D community!to please everyone is becoming a mish-mash of conflicting, overlapping features.I know and I am constantly surprised when you release a new DMD version and a lot of NG ideas are in there. I also realize that you need to try work through all the suggestions to see which features are REALLY needed by many people. But sometimes it seems that there are lots of people in the NG who all agree that something should be changed and there is no comment from you anywhere to be seen. Which doesn't mean that you don't listen, of course, because a month later this feature may very well be in the language. Or it may not because you have never had a problem with it yourself (see switch).Just to avoid misunderstandings: I believe every language should be designed by a single individual, since the compromises you get with design groups are often worse than the simple bad decisions a single person can make.Design-by-committee suffers from the "vote for my feature and I'll vote for yours" madness. And it still is no guarantee that wretched misfeatures won't get in the language, I submit C++'s 'export' as the canonical example <g>. That said, there is still a time and a place for a standards committee for a language, but that is after it is designed and all major features are in place.
May 30 2004
Knud Sørensen wrote:If not special care at taken the intelligence of a group is often the average of its members.One of my favorite authors (Terry Pratchett) wrote that "the IQ of a mob is the IQ of its dumbest member divided by the number of participants". It is not quite the same for academic working groups, but there is a similar tendency ;). Hauke
May 30 2004
Walter wrote:Because int and bool are completely different types. True bools prevent errors, like the often seen newbie problem "while(x=7)". That would not be possible if "while" required a true boolean.If a bool is simply a 32 bit value where 0 means false and !=0 means true then no conversion is necessary.Then just use an int. I just don't see what the problem is.Well if there is none then why don't you use bool for islower? It clearly returns a boolean value (true or false), yet you use int because using bool/bit would be slower. If there was a real boolean type then the compiler would have the freedom of doing such optimizations implicitly by just considering any nonzero value as true.But in my experience bool variables are very rarely compared to each other. Most of the time they are set to true or false or their true-ness is checked. There is no additional overhead for this.And there is none in D.The problem is I'm a thousand or two messages behind in reading the n.g. Even when I do post replies, that frequently inspires a whole ream of new postings. So the more I read and post, the further I get behind. I'm currently trying to wrap up reading the January postings. I'm not complaining, however, since the huge volume of messages is a wonderful sign of the health of the D community!Would it help if volunteers posted summaries of dead threads? Presenting all arguments and counter-arguments in a condensed manner? Hauke
May 30 2004
"Hauke Duden" <H.NS.Duden gmx.net> wrote in message news:c9dm9m$120g$1 digitaldaemon.com...newThe problem is I'm a thousand or two messages behind in reading the n.g. Even when I do post replies, that frequently inspires a whole ream ofsignpostings. So the more I read and post, the further I get behind. I'm currently trying to wrap up reading the January postings. I'm not complaining, however, since the huge volume of messages is a wonderfulI think you'll find that's more than a full time job <g>.of the health of the D community!Would it help if volunteers posted summaries of dead threads? Presenting all arguments and counter-arguments in a condensed manner?
May 30 2004
This reply will make a lot of people really really happy! Walter is thinking about package level acces and default parameters! :) :) :) "Walter" <newshound digitalmars.com> wrote in message news:c9d6pi$d0l$1 digitaldaemon.com..."Hauke Duden" <H.NS.Duden gmx.net> wrote in message news:c9cguf$2hue$1 digitaldaemon.com...moduleWhy are large files a problem? And why can't sub-parts of a largebeaI'll go review the thread, but at the moment I have a hard time imagining why members should be private when they need to be accessed by tens of thousands of lines of other code. But the package level access sounds likeput in other modules?There was a big thread about this the other day called "Module with multiple files". The main problem is that when multiple classes need to collaborate with each other, i.e. if they need friend access, then you have to put them into the same file. With some kinds of class libraries that can mean huge files with tens of thousands of lines of code, which is impossible to manage efficiently when you have multiple programmers working on the classes at the same time. A "package" access level would help, as would the ability to split a module into multiple files (for example, the option to use a directory as a module).good feature to add.boolBut the overloading problem also plays into it: if you want to break a module into sub-modules then all overloading functions must be in the same file. This can be counter-intuitive, as it is often more straightforward to put any global functions into the same file as the classes it takes as arguments.One can overload functions from different import scopes using the 'alias' capability. I believe this explicit control over function overloading is better than C++ for handling very large programs - in C++ with its global overloading and ADL one can get really lost as to which functions are 'in play' for overloading.Seeing the lengths people go to try to emulate default function arguments makes it pretty obvious that I need to add it to the language, I'd underestimated it.I'm talking about DMD 0.91 here. The problem appears when you try to have different mixins that provide functions with the same name but different signatures. Again, the importing algorithm is the culprit. And the reason I wanted to do this is to provide a mixin with the "dummy" functions you need to write to get default values for function arguments. This is all described in more detail in my another of my posts: http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/2456I 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.)It is the same if you use global functions, since they overload in the same way, so this kind of thing: class Stream; void store(Stream s,String x); <other file> void store(Stream s,MyClass c); doesn't work either. Because of this you cannot add support for, for example, storing new types to a stream class without using runtime polymorphy. And that is a problem because D also has structs which cannot implement interfaces, so you cannot add support for "being stored" to any struct whose base class you cannot control.There's got to be a better way <g>.I like that it has a bool type but unfortunately and in contrast to one of the goals of this type theabool/bit). That's to create a bool from an int. This overhead isn't there once it isYou told me yourself. You said you use "int" as the return type for islower and isupper because having ==0, !=0 semantics usually takes two operations less than having ==0,==1 semantics (as you'd have within D is actually slower than an intI don't think it is slower.bool. I don't know of any conceivable implementation of bool (and that includes C++'s bool) that doesn't have this overhead in converting to a bool.(MatthewI have been surprised at the amount of controversy over a bool typeYes, but C++ is my current language. Switching languages means a lot of work, so D has to offer compelling advantages. It fails to do so with the bool type.and it can be implicitly converted to integers.So it can, too, in C++, so that's not a reason to prefer C++ <g>.is solidly in your camp on this, too!). I recall many l-o-n-g threads in newsgroups over the semantics of bool to C years ago.newsgroupbut II'll argue here that I think function overloading is greatly overused,A good point. But also consider that I wouldn't have created thisknow I'm in a minority on that.Then you need to ask yourself whether you create the language just for yourself or also for the "majority". It is your decision of course, but if other people use lots of overloading and you want them to use your language ...if I wasn't interested in other peoples' views. D has grown and improved a lot based on feedback from the members here. But the risk D runs in trying to please everyone is becoming a mish-mash of conflicting, overlapping features.I want to be honest here: most of the stuff I mentioned here is by itself not enough for me to "condemn" the language. Otherwise I wouldn't be posting here. But it adds up.I appreciate you taking the time to post your thoughts on it here.One of the most important issues for me is still the lack of default values for function arguments. To give you an example, I recently wrote a String interface plus different implementations as a "tryout project" for D. That string interface has 48 "real" methods and 36 dummy methods to implement default values (almost all methods have one or two default arguments). So for each implementation you have to write almost twice as many methods as really necessary. My attempts to work around this limitation with mixins were the reason why I kept bumping into the mixin and overloading problems. Hauke
May 30 2004
In article <c9d6pi$d0l$1 digitaldaemon.com>, Walter says... .Seeing the lengths people go to try to emulate default function arguments makes it pretty obvious that I need to add it to the language, I'd underestimated it.Argument Stanzas Since you're thinking about the optionals, I'll mention a "wild idea" I've been thinking about. Often it would be great to have optional parameters but there are multiple parameters that should be independantly optional. foo(int x, int y, int z = 0, int p, int q, int r = 3); In C++ this is impossible. My suggestion is that argument lists could be broken up into "stanzas" using ";". Maybe each set is grouped by function. foo(int x, int y, int z = 0; int p, int q, int r = 3); Called like this: foo(1, 2, 3; 4, 5, 6) Or: foo(1, 2; 4, 5) Each "stanza" can have however many optional parameters at the end. So if the first stanza corresponds to coordinates, and the second to socket parameters, I can extend either independantly. Conceptually, it's more like this: <-> foo(int x, int y, int z = 0; <-> int p, int q, int r = 3); This could still be done during function argument matching and should be about the same implementation as regular optional parameters, (assuming the C++ idiom of inserting defaults in the calling function's argument list.) As normal arguments are to a list, so stanzas are to several lists. So naturally, if the last stanza contained ONLY optional parameters, it could be omitted, and so on. My only reservation is that syntax may be ambiguous, although I can't see where it breaks. Whaddaya think? KevinThat's to create a bool from an int. This overhead isn't there once it is a bool. I don't know of any conceivable implementation of bool (and that includes C++'s bool) that doesn't have this overhead in converting to a bool.There are equivalences in the math; if true means nonzero, you can use "|" for "||". If false means "!= -1", you could use "&" for "&&". Sadly, no middle ground, which suggests to me that there IS no mathematical solution. Maybe use the high bit to indicate true and the low bit for false? I'm kidding. Kevin
Jun 01 2004
"Kevin Bealer" <Kevin_member pathlink.com> wrote in message news:c9jt8i$pfv$1 digitaldaemon.com...My only reservation is that syntax may be ambiguous, although I can't seewhereit breaks. Whaddaya think?There's no technical problem with it, but I'd want to see more demand for it first <g>.
Jun 02 2004
In article <c9lb8p$2tm2$2 digitaldaemon.com>, Walter says..."Kevin Bealer" <Kevin_member pathlink.com> wrote in message news:c9jt8i$pfv$1 digitaldaemon.com...Like I said, just a wild idea, not a feature request. But optional/default arguments would be really nice, and/or a type safe "va_args" replacement. Here's another wild idea: a typesafe "..." mechanism. I'm sure this needs some massaging for performance et al, but the following class is an example of a possible "va" syntax. Briefly, when a function X uses "...", the system looks for "X_opArg()" overloads to handle the "..." parts. Here it is with extended opCall(): class printf2 { void opCall(int x, ...) { printf("%d: ", x); opArg(...); printf("\n"); } void opCall_opArg(char[] x) { printf("%.*s", x); } void opCall_opArg(double x) { printf("%g", x); } void opCall_opArg(uint x) { printf("%d", x); } void print_two(...); void print_two_opCall(); // and so on } int main() { printf_two printf2 = new printf_two; double dd = 0.345; uint uu = 123; printf2("hello ", dd, " ", uu, "\n"); return 0; } I know, printf() is fast, cout slower, so why use seperate calls. In any case, it would be nice to have some sort of mechanism for this KIND of task, and the function call technique allows a kind of "translation to C object model", because the static type system can already overload in this way. An alternative would be to only allow this for "opCall" and use "opArg" without any special function name prefix. If you need more than one extended function, create inner classes, used as data members, to field the calls. Mostly, I think "..." is currently used for standalone functions anyway, so the hypothetical "printf" here would be a global object or implicit function returning a singleton, etc. But I think whatever mechanism would need to permit multiple such interfaces per class. .. Maybe for D v3.0 (cough)? KevinMy only reservation is that syntax may be ambiguous, although I can't seewhereit breaks. Whaddaya think?There's no technical problem with it, but I'd want to see more demand for it first <g>.
Jun 02 2004
Kevin Bealer wrote:Since you're thinking about the optionals, I'll mention a "wild idea" I've been thinking about. [...] My suggestion is that argument lists could be broken up into "stanzas" using ";". Maybe each set is grouped by function. foo(int x, int y, int z = 0; int p, int q, int r = 3); Called like this: foo(1, 2, 3; 4, 5, 6) Or: foo(1, 2; 4, 5)Before thinking about that too deeply, I would rather go for the full solution of named arguments (like in Python). This certainly is a more intrusive language feature which will not be decided overnight, but in the long run, it just is far more powerful, useful and descriptive than such a hard-to-read extension.
Jun 02 2004
On Sat, 29 May 2004 16:58:52 -0700, Walter wrote: [snip]Why are large files a problem?The problem I have with large files is how to enable a group of developers to independantly and simultaneously modify sections of it without losing something. If only one coder can check-out the file at a time, I have others in the team waiting on that coder to check it in again. If I allow multiple checkouts, then there are issues about merging check ins without making mistakes. This can be quite a time-consuming manual effort. A set of smaller files that together make a single 'module' is a much more practical solution for a team of coders. Right now, I have a large file (33,400 lines) that I would *love* to split up so that I can have a team of coders simultaneously working on various parts. -- Derek 31/May/04 11:53:10 AM
May 30 2004