digitalmars.D - Reasons for current function overload spec
- Sean Reque (3/3) Jan 04 2008 I did a search on this forum for function overloading and for HiddenFunc...
- Sean Kelly (3/6) Jan 04 2008 Do you mean function overloading or overriding?
- Robert DaSilva (3/27) Jan 04 2008 HiddenFuncError is cause by overriding overloaded functions so I would
- Sean Reque (2/7) Jan 04 2008 I probably don't have the terminology right. Maybe the term is 'overload...
- Sean Kelly (6/13) Jan 04 2008 Oh right, I'd completely forgotten this feature :-) The discussion took...
- Sean Reque (43/43) Jan 05 2008 Thanks for the links! I was able to find through it two very long discus...
- Sean Reque (4/6) Jan 05 2008 I meant to say here that as far as I know this error can ONLY be debugge...
- Manfred Nowak (3/5) Jan 05 2008 No crash on my machine XP32, dmd 1.029.
- sean reque (2/10) Jan 05 2008 I'm using D 2.009, and the crashing behavior is part of the 2.0 spec. Th...
- Manfred Nowak (3/4) Jan 06 2008 oops. Should have read your original post.
- Sean Kelly (8/9) Jan 05 2008 Here are some of the posts that I was thinking of in particular:
- Jason House (19/36) Jan 06 2008 http://www.digitalmars.com/pnews/read.php?server=news.digitalmars.com&gr...
- Robert DaSilva (3/43) Jan 06 2008 This happen when you overRIDE an overLOADed function, but you don't
- Jason House (4/6) Jan 06 2008 That sounds like something very easy to detect at compile-time. Are the...
- James Dennett (9/16) Jan 06 2008 In general, it's a bad idea to have overloaded virtual functions.
- Janice Caron (2/3) Jan 07 2008 Perhaps, but this is D, where member functions are virtual by default.
- James Dennett (17/21) Jan 07 2008 That's OK, it just makes writing safe code take a little more
- Sean Reque (5/8) Jan 08 2008 Well if everyone is agreed that virtual function overriding is a bad ide...
- Robert Fraser (3/4) Jan 08 2008 Warnings aren't part of the D spec, so compilers are free to implement
I did a search on this forum for function overloading and for HiddenFunc and I didn't find anything, so I thought I would pose the question: is everyone generally agreed that the way function overloading works in 2.0 is a good idea? I think anything that can cause runtime errors is generally something to be avoided, and reading about how HiddenFuncErrors can be raised threw up red flags for me as a bad thing. I can understand wanting to simpify things over C++, but not being able to access publicly declared super class member functions, not for technical reasons, but because of language design, and even worse, not revealing the errors until runtime, seems to me like something that will cause more problems in the long run than anything else. Today I finally got gtkD to compile and run successfully on the dmd 2.008 compiler, and much time was spent figuring out how to get a debugger working so I could get a stack trace to track down a HiddenFuncError in a very long class hierarchy so I could put in the correct alias declaration in the right class. This kind of So basically I just wanted to learn more about the justifications for this design and how likely this feature will become permanent.
Jan 04 2008
Sean Reque wrote:I did a search on this forum for function overloading and for HiddenFunc and I didn't find anything, so I thought I would pose the question: is everyone generally agreed that the way function overloading works in 2.0 is a good idea? I think anything that can cause runtime errors is generally something to be avoided, and reading about how HiddenFuncErrors can be raised threw up red flags for me as a bad thing. I can understand wanting to simpify things over C++, but not being able to access publicly declared super class member functions, not for technical reasons, but because of language design, and even worse, not revealing the errors until runtime, seems to me like something that will cause more problems in the long run than anything else. Today I finally got gtkD to compile and run successfully on the dmd 2.008 compiler, and much time was spent figuring out how to get a debugger working so I could get a stack trace to track down a HiddenFuncError in a very long class hierarchy so I could put in the correct alias declaration in the right class. This kind ofDo you mean function overloading or overriding? Sean
Jan 04 2008
Sean Kelly wrote:Sean Reque wrote:HiddenFuncError is cause by overriding overloaded functions so I would say both.I did a search on this forum for function overloading and for HiddenFunc and I didn't find anything, so I thought I would pose the question: is everyone generally agreed that the way function overloading works in 2.0 is a good idea? I think anything that can cause runtime errors is generally something to be avoided, and reading about how HiddenFuncErrors can be raised threw up red flags for me as a bad thing. I can understand wanting to simpify things over C++, but not being able to access publicly declared super class member functions, not for technical reasons, but because of language design, and even worse, not revealing the errors until runtime, seems to me like something that will cause more problems in the long run than anything else. Today I finally got gtkD to compile and run successfully on the dmd 2.008 compiler, and much time was spent figuring out how to get a debugger working so I could get a stack trace to track down a HiddenFuncError in a very long class hierarchy so I could put in the correct alias declaration in the right far as I'm aware.Do you mean function overloading or overriding? Sean
Jan 04 2008
Sean Kelly Wrote:Do you mean function overloading or overriding? SeanI probably don't have the terminology right. Maybe the term is 'overload resolution'? Robert described it right, I think. It occurs when you define a function of the same name as one or more functions in a superclass, which effectively shadows the super class function(s). If an object of the class is then up-casted to the super class with a shadowed function and that function is then called, a runtime exception is thrown.
Jan 04 2008
Sean Reque wrote:Sean Kelly Wrote:Oh right, I'd completely forgotten this feature :-) The discussion took place in this forum a few months ago under the subject "Overloading/Inheritance issue." Here is a link to the first post: http://www.digitalmars.com/pnews/read.php?server=news.digitalmars.com&group=digitalmars.D&artnum=56295 SeanDo you mean function overloading or overriding? SeanI probably don't have the terminology right. Maybe the term is 'overload resolution'? Robert described it right, I think. It occurs when you define a function of the same name as one or more functions in a superclass, which effectively shadows the super class function(s). If an object of the class is then up-casted to the super class with a shadowed function and that function is then called, a runtime exception is thrown.
Jan 04 2008
Thanks for the links! I was able to find through it two very long discussions on this issue. One point that was brought up is that the reason D implements overload resolution the way it currently does is because c++ did it the same way for 20 years and no one complained. Well, a lot of post were made about different aspects of the issue, so I want to just focus on the area I have the biggest problem with. I didn't read EVERY post, but I hope this is a newer way of looking at it. The following C++ program compiles fine: #include <stdio.h> class A { public: void print(int i) { printf("you gave me integer %d\n", i); } }; class B : public A { public: void print(char c) { printf("you gave me character %c\n", c); } }; void overload_res_test(A& a) { a.print(1); } int main() { B b; overload_res_test(b); return 0; } The following --equivalent-- D program crashes with a runtime exception that can be debugged as far as I know with a debugger: class A { public: void print(int i) { printf("you gave me integer %d\n", i); } } class B : A { public: void print(char c) { printf("you gave me character %c\n", c); } } void overload_res_test(A a) { a.print(1); } void main() { scope B b = new B(); overload_res_test(b); } Like I said in my first post, I had to spend a long time getting a debugger to work when I tried compiling a hello world app with gtkD and I got a hidden function error. The shadowed method declaration was about 7 classes up the hierarchy, while the actual function that did the shadowing was about 3 or 4 up the hierarchy. The worst part about this is that the error is only revealed at runtime and only if the function is called under certain conditions. For a strongly-typed compiled language, in my opinion this is disastrous, and it's not what either C++ or Java does.
Jan 05 2008
Sean Reque Wrote:The following C++ program compiles fine:Oops! I meant to say it compiles and runs fine.The following --equivalent-- D program crashes with a runtime exception that can be debugged as far as I know with a debugger:I meant to say here that as far as I know this error can ONLY be debugged reasonably with a debugger. The final thing I had to note was that I recompiled the D program, declaring the functions as final, and it actually ran successfully. I recompiled the c++ program with the functions declared as virtual and it still ran fine. So the c++ function works for both virtual and static functions, while the D program works with static functions and crashes at runtime with virtual functions.
Jan 05 2008
Sean Reque wroteThe following --equivalent-- D program crashes with a runtime exceptionNo crash on my machine XP32, dmd 1.029. -manfred
Jan 05 2008
Manfred Nowak Wrote:Sean Reque wroteI'm using D 2.009, and the crashing behavior is part of the 2.0 spec. That's one reason why I was posting, to find out if this behavior is already permanently in the language or still in alpha.The following --equivalent-- D program crashes with a runtime exceptionNo crash on my machine XP32, dmd 1.029. -manfred
Jan 05 2008
sean reque wrote:crashing behavior is part of the 2.0 spec.oops. Should have read your original post. -manfred
Jan 06 2008
Sean Reque wrote:Thanks for the links! I was able to find through it two very long discussions on this issue. One point that was brought up is that the reason D implements overload resolution the way it currently does is because c++ did it the same way for 20 years and no one complained. Well, a lot of post were made about different aspects of the issue, so I want to just focus on the area I have the biggest problem with. I didn't read EVERY post, but I hope this is a newer way of looking at it.Here are some of the posts that I was thinking of in particular: http://www.digitalmars.com/pnews/read.php?server=news.digitalmars.com&group=digitalmars.D&artnum=56391 http://www.digitalmars.com/pnews/read.php?server=news.digitalmars.com&group=digitalmars.D&artnum=56414 http://www.digitalmars.com/pnews/read.php?server=news.digitalmars.com&group=digitalmars.D&artnum=56418 The different overload resolution schemes between C++ and D may be a factor as well. Sean
Jan 05 2008
Sean Kelly wrote:Sean Reque wrote:http://www.digitalmars.com/pnews/read.php?server=news.digitalmars.com&group=digitalmars.D&artnum=56391Thanks for the links! I was able to find through it two very long discussions on this issue. One point that was brought up is that the reason D implements overload resolution the way it currently does is because c++ did it the same way for 20 years and no one complained. Well, a lot of post were made about different aspects of the issue, so I want to just focus on the area I have the biggest problem with. I didn't read EVERY post, but I hope this is a newer way of looking at it.Here are some of the posts that I was thinking of in particular:http://www.digitalmars.com/pnews/read.php?server=news.digitalmars.com&group=digitalmars.D&artnum=56414http://www.digitalmars.com/pnews/read.php?server=news.digitalmars.com&group=digitalmars.D&artnum=56418The different overload resolution schemes between C++ and D may be a factor as well. SeanWow... That's a pretty evil bug. I think I have to agree with Sean Reque in that this type of thing really can't sit around as a bomb at runtime. I was under the impression that shadowing superclass functions was an ERROR and that if a function was to be defined with the same name that it had to use the override keyword to make the programmer's intent clear. I'm almost certain that shadowing variables in functions is an ERROR. This seems even more evil. I'd really, really hope that a language that includes design by contract, unit testing, and enhanced const correctness would do a better job handling this class of problem. I'd expect some kind of specialized syntax to mark this type of questionable code as the programmer's intent. It seems to me that in the squareIt example, accessing a D instance via a B reference should be illegal... Maybe I should go back and read that whole thread on this topic before I post more...
Jan 06 2008
Jason House wrote:Sean Kelly wrote:This happen when you overRIDE an overLOADed function, but you don't overRIDE all of the overLOADs.Sean Reque wrote:http://www.digitalmars.com/pnews/read.php?server=news.digitalmars.com&group=digitalmars.D&artnum=56391 http://www.digitalmars.com/pnews/read.php?server=news.digitalmars.com&group=digitalmars.D&artnum=56414 http://www.digitalmars.com/pnews/read.php?server=news.digitalmars.com&group=digitalmars.D&artnum=56418Thanks for the links! I was able to find through it two very long discussions on this issue. One point that was brought up is that the reason D implements overload resolution the way it currently does is because c++ did it the same way for 20 years and no one complained. Well, a lot of post were made about different aspects of the issue, so I want to just focus on the area I have the biggest problem with. I didn't read EVERY post, but I hope this is a newer way of looking at it.Here are some of the posts that I was thinking of in particular:The different overload resolution schemes between C++ and D may be a factor as well. SeanWow... That's a pretty evil bug. I think I have to agree with Sean Reque in that this type of thing really can't sit around as a bomb at runtime. I was under the impression that shadowing superclass functions was an ERROR and that if a function was to be defined with the same name that it had to use the override keyword to make the programmer's intent clear. I'm almost certain that shadowing variables in functions is an ERROR. This seems even more evil. I'd really, really hope that a language that includes design by contract, unit testing, and enhanced const correctness would do a better job handling this class of problem. I'd expect some kind of specialized syntax to mark this type of questionable code as the programmer's intent. It seems to me that in the squareIt example, accessing a D instance via a B reference should be illegal... Maybe I should go back and read that whole thread on this topic before I post more...
Jan 06 2008
Robert DaSilva wrote:This happen when you overRIDE an overLOADed function, but you don't overRIDE all of the overLOADs.That sounds like something very easy to detect at compile-time. Are there practical situations with large ovrload sets where this would be a real pain for the programmer?
Jan 06 2008
Jason House wrote:Robert DaSilva wrote:In general, it's a bad idea to have overloaded virtual functions. A virtual function is a customization point; having overloads means that each customization has to be sure to overload them all in a consistent manner. Much better to have non-virtual overloads which forward to a single, general, virtual function. Then the problem disappears. I think that diagnosing overloaded virtuals would be entirely reasonable. -- JamesThis happen when you overRIDE an overLOADed function, but you don't overRIDE all of the overLOADs.That sounds like something very easy to detect at compile-time. Are there practical situations with large ovrload sets where this would be a real pain for the programmer?
Jan 06 2008
On 1/7/08, James Dennett <jdennett acm.org> wrote:In general, it's a bad idea to have overloaded virtual functions.Perhaps, but this is D, where member functions are virtual by default.
Jan 07 2008
Janice Caron wrote:On 1/7/08, James Dennett <jdennett acm.org> wrote:That's OK, it just makes writing safe code take a little more effort. Writing safe code has always taken effort. Sure, it's nice when the language helped rather than hindered, but no one language will get all trade-offs right. There are other reasons why a _programmer's_ default should be to make a function non-virtual, most significantly that writing (and designing) a solid specification for virtual functions is harder than for non-virtual functions as they have three components: what the default implementation does, what an override is required to do, and what the override is not allowed to do (e.g., if it's called when the object is not in a state which permits calling certain other methods on it). Most functions don't need that much complexity, and a type which has mostly virtual functions almost never has adequate documentation unless it's a pure interface. -- JamesIn general, it's a bad idea to have overloaded virtual functions.Perhaps, but this is D, where member functions are virtual by default.
Jan 07 2008
James Dennett Wrote: ps, but this is D, where member functions are virtual by default.That's OK, it just makes writing safe code take a little more effort.Well if everyone is agreed that virtual function overriding is a bad idea, could we at least get some kind of a warning message at compile time when it happens? If the compiler is smart enough to stuff the v-table with garbage functions, it could also inform us that it is doing so. Of course, I still don't agree that the compiler shouldn't be placing the --correct-- functions in the v-table. The way it is now, whenever a programmer decides to create a class that inherits from another, he has to understand the entire class hierarchy of that inherited class to be sure he doesn't accidentally override a function that disables the class from taking advantage of inclusion polymorphism. This HiddenFuncError feature breaks inclusion polymorphism, because having a class B inherit from class A no longer implies that an object of type B is fully capable of acting as an object of type A, regardless of whether or not the programmer intended to make it that way. That's a huge deal, because most of the advantage of OOP comes from this type of polymorphism, more so than encapsulation and data-aggregation. The fact that this important piece of information is only revealed under specific conditions at runtime is what makes it so dangerous. In my opinion, this alone makes D OOP inferior to that of most other modern languages. If this is going to be a permanent feature, then there should at least be a way to get a warning at compile time that a class is hiding functions from a superclass, which could cause your entire program to crash.
Jan 08 2008
Sean Reque wrote:Well if everyone is agreed that virtual function overriding is a bad idea, could we at least get some kind of a warning message at compile time when it happens?Warnings aren't part of the D spec, so compilers are free to implement them however thy like.
Jan 08 2008