www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Could new keyword help function hijacking and prevented aliasing

reply Matthew Ong <ongbp yahoo.com> writes:
Hi All,

Currently within D, to make use of a parent class method you have to do:
class Parent{
     void methodA(int x){...}
}

class Child : Parent{
    // I understand that it has to do with preventing accidental hijacking
     alias Parent.methodA methodA;
     void methodA(long x){...}
}

void main(string[]){
     Child obj=new Child();
     obj.methodA(1); // expecting to call Child.methodA but calling 
Parent.methodA;
}

and also from this URL.
http://www.digitalmars.com/d/2.0/function.html
If, through implicit conversions to the base class, those other 
functions do get called, an std.HiddenFuncError exception is raised.

-----------------------------------------------------------------------
That is to prevent silently changing the program's behavior. b.foo(1) 
could happily be a call to B.foo(long) today. Imagine one of the base 
classes changed and now there is A.foo(int). Then our b.foo(1) would 
silently start calling that new function. That would cause a tough bug.
Ali  // a Better explanation than the document for the current syntax.
------------------------------------------------------------------------

However, there is a foreseeable problem coming when a program grow.
How about when the inheritance tree becomes deeper than 4? And more and 
more overloaded functions are in different classes? That does not meant 
the calling class/method has a sense if it is calling from Child or 
Parent. Because, those 2 classes source code might not be available for 
coder. How does the coder knows about that?

Does it mean we have to do more alias at child class at the bottom? 
Harder to issues solve in the child class at the bottom of the tree.

It seem to me that the entire purpose is just to protect auto promotion 
matching method signature in the base to avoid function hijacking.

How about doing this another way? Just a suggestion if you like to avoid 
parent function from accidental hijack but still needs to be public. New 
keywords are needed: nooverload and inheritall

class Parent{
     nooverload void methodA(int x){...} // entirely deny this name to 
be overloaded.
}

// this would have avoided the aliasing all over child class and still 
allow child class to see any >public< method of the parent.

class Child: inheritall Parent{ // auto inheriting all parent methods 
except private ones. As per usual also for package/protected...
     void methodA(long x){...} // compilation error. because nooverload 
is used at Parent
     void methodA(string x){...} // compilation error. because nooverload
     ... etc

     void methodB(){
         methodA(123); // No error now, and the entire hijacking is avoided.
     }
}

void main(string[] args){
    Child obj=new Child();
    obj.methodB(); // no problem
    obj.methodA(123); // no accidental hijacking...Always use parent class.
}

Reverse sequence as Ali has shown can also be avoided because if someone 
does that by adding 'new' methodA in parent where child already has 
methodA overloaded already without knowledge. Show up in compilation 
exception for such cases with -w flag on.

How about that? Possible solution?

-- 
Matthew Ong
email: ongbp yahoo.com
May 26 2011
next sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2011-05-27 08:34, Matthew Ong wrote:
 Hi All,

 Currently within D, to make use of a parent class method you have to do:
 class Parent{
 void methodA(int x){...}
 }

 class Child : Parent{
 // I understand that it has to do with preventing accidental hijacking
 alias Parent.methodA methodA;
 void methodA(long x){...}
 }

 void main(string[]){
 Child obj=new Child();
 obj.methodA(1); // expecting to call Child.methodA but calling
 Parent.methodA;
 }

 and also from this URL.
 http://www.digitalmars.com/d/2.0/function.html
 If, through implicit conversions to the base class, those other
 functions do get called, an std.HiddenFuncError exception is raised.

 -----------------------------------------------------------------------
 That is to prevent silently changing the program's behavior. b.foo(1)
 could happily be a call to B.foo(long) today. Imagine one of the base
 classes changed and now there is A.foo(int). Then our b.foo(1) would
 silently start calling that new function. That would cause a tough bug.
 Ali // a Better explanation than the document for the current syntax.
 ------------------------------------------------------------------------

 However, there is a foreseeable problem coming when a program grow.
 How about when the inheritance tree becomes deeper than 4? And more and
 more overloaded functions are in different classes? That does not meant
 the calling class/method has a sense if it is calling from Child or
 Parent. Because, those 2 classes source code might not be available for
 coder. How does the coder knows about that?

 Does it mean we have to do more alias at child class at the bottom?
 Harder to issues solve in the child class at the bottom of the tree.

 It seem to me that the entire purpose is just to protect auto promotion
 matching method signature in the base to avoid function hijacking.

 How about doing this another way? Just a suggestion if you like to avoid
 parent function from accidental hijack but still needs to be public. New
 keywords are needed: nooverload and inheritall

 class Parent{
 nooverload void methodA(int x){...} // entirely deny this name to be
 overloaded.
 }

 // this would have avoided the aliasing all over child class and still
 allow child class to see any >public< method of the parent.

 class Child: inheritall Parent{ // auto inheriting all parent methods
 except private ones. As per usual also for package/protected...
 void methodA(long x){...} // compilation error. because nooverload is
 used at Parent
 void methodA(string x){...} // compilation error. because nooverload
 ... etc

 void methodB(){
 methodA(123); // No error now, and the entire hijacking is avoided.
 }
 }

 void main(string[] args){
 Child obj=new Child();
 obj.methodB(); // no problem
 obj.methodA(123); // no accidental hijacking...Always use parent class.
 }

 Reverse sequence as Ali has shown can also be avoided because if someone
 does that by adding 'new' methodA in parent where child already has
 methodA overloaded already without knowledge. Show up in compilation
 exception for such cases with -w flag on.

 How about that? Possible solution?
How big is this problem in practice, how often do need overload (NOT override) a method in the subclass that exists in the super class? -- /Jacob Carlborg
May 26 2011
parent Matthew Ong <ongbp yahoo.com> writes:
On 5/27/2011 2:54 PM, Jacob Carlborg wrote:
Hi Jacob,

See some of the source code shown here. I did not code them, but can 
sense the pattern is not too productive brain cycle invested.
Cycle= trying to locate up the tree of inherited object.

BTW, default D documentation is Not too friendly for inheritance tree 
navigation. Unlike in java.

Not to promote deep inheritance tree. I actually like to flatten them 
using interface template and adaptor pattern. Memory usage and object
tree creation clock cycle is smaller.

With overloading and also runtime dynamic method invocation, it makes

http://hg.dsource.org/projects/dwt2/file/d00e8db0a568/base/src/java/io/ByteArrayInputStream.d
 How big is this problem in practice, how often do need overload (NOT
 override) a method in the subclass that exists in the super class?
Actually, the argument of reason of using alias is to prevent hijacking as mentioned by others in the URL. Overloading is actually more frequent than overriding base on data modeling because of polymorphic nature of the OOP concept. I can see no point of doing various naming for a single calculation. Yes, it can be done with various different name, Google Go does NOT have overloading. ie: // Please note, the internal logics of such methods may or may be the same, because of dependent of business logic. Hence, functional template might not be needed. class RiskAccessment{ double calculate(NormalAccount acc, double intrest){...} double calculate(CurrentAccount acc, double intrest){...} double calculate(FixedDeposit acc, double intrest){...} double calculate(FixedIncome acc, double intrest){...} double calculate(Equity acc, double intrest){...} double calculate(FixedAssets acc, double intrest){...} } and many other such patterns. Overriding is for entirely different thing. Hence, I suggested the 2 new keywords solutions. -- Matthew Ong email: ongbp yahoo.com
May 27 2011
prev sibling next sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Fri, 27 May 2011 02:34:34 -0400, Matthew Ong <ongbp yahoo.com> wrote:

 Hi All,

 Currently within D, to make use of a parent class method you have to do:
 class Parent{
      void methodA(int x){...}
 }

 class Child : Parent{
     // I understand that it has to do with preventing accidental  
 hijacking
      alias Parent.methodA methodA;
      void methodA(long x){...}
 }

 void main(string[]){
      Child obj=new Child();
      obj.methodA(1); // expecting to call Child.methodA but calling  
 Parent.methodA;
 }

 and also from this URL.
 http://www.digitalmars.com/d/2.0/function.html
 If, through implicit conversions to the base class, those other  
 functions do get called, an std.HiddenFuncError exception is raised.

 -----------------------------------------------------------------------
 That is to prevent silently changing the program's behavior. b.foo(1)  
 could happily be a call to B.foo(long) today. Imagine one of the base  
 classes changed and now there is A.foo(int). Then our b.foo(1) would  
 silently start calling that new function. That would cause a tough bug.
 Ali  // a Better explanation than the document for the current syntax.
 ------------------------------------------------------------------------

 However, there is a foreseeable problem coming when a program grow.
 How about when the inheritance tree becomes deeper than 4? And more and  
 more overloaded functions are in different classes? That does not meant  
 the calling class/method has a sense if it is calling from Child or  
 Parent. Because, those 2 classes source code might not be available for  
 coder. How does the coder knows about that?

 Does it mean we have to do more alias at child class at the bottom?  
 Harder to issues solve in the child class at the bottom of the tree.

 It seem to me that the entire purpose is just to protect auto promotion  
 matching method signature in the base to avoid function hijacking.

 How about doing this another way? Just a suggestion if you like to avoid  
 parent function from accidental hijack but still needs to be public. New  
 keywords are needed: nooverload and inheritall

 class Parent{
      nooverload void methodA(int x){...} // entirely deny this name to  
 be overloaded.
 }

 // this would have avoided the aliasing all over child class and still  
 allow child class to see any >public< method of the parent.

 class Child: inheritall Parent{ // auto inheriting all parent methods  
 except private ones. As per usual also for package/protected...
      void methodA(long x){...} // compilation error. because nooverload  
 is used at Parent
      void methodA(string x){...} // compilation error. because nooverload
      ... etc

      void methodB(){
          methodA(123); // No error now, and the entire hijacking is  
 avoided.
      }
 }

 void main(string[] args){
     Child obj=new Child();
     obj.methodB(); // no problem
     obj.methodA(123); // no accidental hijacking...Always use parent  
 class.
 }

 Reverse sequence as Ali has shown can also be avoided because if someone  
 does that by adding 'new' methodA in parent where child already has  
 methodA overloaded already without knowledge. Show up in compilation  
 exception for such cases with -w flag on.

 How about that? Possible solution?
I don't think it will work that well. Consider how function hijacking happens. For instance, the parent class author may not even know his code is being overridden, and he may simply not mark his base function as nooverload. Let's say that the child is inheriting all the parent's methods because he wanted a different method (an already existing one), and the author of the parent class adds methodA (without the nooverload attribute) after the child is already written. That's an unintentional hijack. The problem is the child is relying on the parent to cooperate in preventing hijacking, instead of controlling whether its functions can be hijacked or not. In the current solution, the system warns me or throws an error if a function becomes hijacked. If this happens, I can examine the code and add an alias if needed. It happens rarely for me. Do you have cases where you have to "alias all over the place"? Maybe you are not doing something correctly, you shouldn't need this feature all the time. Note that drastic proposals like this are very unlikely to be accepted. Especially for something that has been in use and not really complained about for years. You need to present a very compelling argument, including real examples is helpful. Also, if there's any way to get rid of adding a keyword, you have a much better shot of success. No keywords have been added to the language for a long time. -Steve
May 27 2011
parent reply Matthew Ong <ongbp yahoo.com> writes:
On 5/27/2011 7:08 PM, Steven Schveighoffer wrote:
 On Fri, 27 May 2011 02:34:34 -0400, Matthew Ong <ongbp yahoo.com> wrote:

 Hi All,

 Currently within D, to make use of a parent class method you have to do:
 class Parent{
 void methodA(int x){...}
 }

 class Child : Parent{
 // I understand that it has to do with preventing accidental hijacking
 alias Parent.methodA methodA;
 void methodA(long x){...}
 }

 void main(string[]){
 Child obj=new Child();
 obj.methodA(1); // expecting to call Child.methodA but calling
 Parent.methodA;
 }

 and also from this URL.
 http://www.digitalmars.com/d/2.0/function.html
 If, through implicit conversions to the base class, those other
 functions do get called, an std.HiddenFuncError exception is raised.

 -----------------------------------------------------------------------
 That is to prevent silently changing the program's behavior. b.foo(1)
 could happily be a call to B.foo(long) today. Imagine one of the base
 classes changed and now there is A.foo(int). Then our b.foo(1) would
 silently start calling that new function. That would cause a tough bug.
 Ali // a Better explanation than the document for the current syntax.
 ------------------------------------------------------------------------

 However, there is a foreseeable problem coming when a program grow.
 How about when the inheritance tree becomes deeper than 4? And more
 and more overloaded functions are in different classes? That does not
 meant the calling class/method has a sense if it is calling from Child
 or Parent. Because, those 2 classes source code might not be available
 for coder. How does the coder knows about that?

 Does it mean we have to do more alias at child class at the bottom?
 Harder to issues solve in the child class at the bottom of the tree.

 It seem to me that the entire purpose is just to protect auto
 promotion matching method signature in the base to avoid function
 hijacking.

 How about doing this another way? Just a suggestion if you like to
 avoid parent function from accidental hijack but still needs to be
 public. New keywords are needed: nooverload and inheritall

 class Parent{
 nooverload void methodA(int x){...} // entirely deny this name to be
 overloaded.
 }

 // this would have avoided the aliasing all over child class and still
 allow child class to see any >public< method of the parent.

 class Child: inheritall Parent{ // auto inheriting all parent methods
 except private ones. As per usual also for package/protected...
 void methodA(long x){...} // compilation error. because nooverload is
 used at Parent
 void methodA(string x){...} // compilation error. because nooverload
 ... etc

 void methodB(){
 methodA(123); // No error now, and the entire hijacking is avoided.
 }
 }

 void main(string[] args){
 Child obj=new Child();
 obj.methodB(); // no problem
 obj.methodA(123); // no accidental hijacking...Always use parent class.
 }

 Reverse sequence as Ali has shown can also be avoided because if
 someone does that by adding 'new' methodA in parent where child
 already has methodA overloaded already without knowledge. Show up in
 compilation exception for such cases with -w flag on.

 How about that? Possible solution?
I don't think it will work that well. Consider how function hijacking happens. For instance, the parent class author may not even know his code is being overridden, and he may simply not mark his base function as nooverload. Let's say that the child is inheriting all the parent's methods because he wanted a different method (an already existing one), and the author of the parent class adds methodA (without the nooverload attribute) after the child is already written. That's an unintentional hijack. The problem is the child is relying on the parent to cooperate in preventing hijacking, instead of controlling whether its functions can be hijacked or not. In the current solution, the system warns me or throws an error if a function becomes hijacked. If this happens, I can examine the code and add an alias if needed. It happens rarely for me. Do you have cases where you have to "alias all over the place"? Maybe you are not doing something correctly, you shouldn't need this feature all the time. Note that drastic proposals like this are very unlikely to be accepted. Especially for something that has been in use and not really complained about for years. You need to present a very compelling argument, including real examples is helpful. Also, if there's any way to get rid of adding a keyword, you have a much better shot of success. No keywords have been added to the language for a long time. -Steve
Hi Steve, Please note that the proposal is not to remove the existing function hijacking detection but as an alternative to the existing aliasing.
Consider how function hijacking happens. For instance, the parent 
class author may not even know his code is being overridden, and he 
may simply not mark his base function as nooverload.
From OO stand point, overloading is NOT overriding. Please do not mix up the two. Fundamentally different. http://users.soe.ucsc.edu/~charlie/book/notes/chap7/sld012.htm
parent class adds methodA (without the nooverload attribute)
If that happens, still flag as function hijacking using existing detection. Please note that I did NOT ask for the removal of using aliasing on existing source code for inherited overloaded function. BTW, default D documentation is Not too friendly for inheritance tree navigation. Unlike in java. However, new keywords can be added to the compiler. So that future code can be written without spending many brain cycle on looking up such alias. Let the compiler do the hard work of AST searching rather than a manual process. We have quad core now a days, even in asia. Have you systemetic go over the proposal I posted and gave your counter arguement? How about the fact that currently there are such aliasing all over the child class. From what I understand D inheritance is Not automatic, if I am wrong do let me know. Do you have cases where you have to "alias all over the place"? news://news.digitalmars.com:119/iri4am$2dl3$1 digitalmars.com http://hg.dsource.org/projects/dwt2/file/d00e8db0a568/base/src/java/io/By eArrayInputStream.d
Maybe you are not doing something correctly, you shouldn't need this 
feature all the time. Not me, others that has coded the dwt and I suspect other code in
instead of controlling whether its functions can be hijacked or not.
Why NOT? If a problem can be prevented easily as an modifier keyword. Hijacking is not a feature, it is a problem correct???
No keywords have been added to the language for a long time.
Perhaps there is no-one that seen different from angle? Most source code development process needs to look at at least 7 different dimensions. Inheritance down the tree, up the tree, interfaces and its implementation, changes over time, testing, cpu cycle, memory creation cycle. That is just single threaded model. That is a tasks burdensome enough for most person. -- Matthew Ong email: ongbp yahoo.com
May 27 2011
next sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Fri, 27 May 2011 07:42:17 -0400, Matthew Ong <ongbp yahoo.com> wrote:

 On 5/27/2011 7:08 PM, Steven Schveighoffer wrote:
 I don't think it will work that well. Consider how function hijacking
 happens. For instance, the parent class author may not even know his
 code is being overridden, and he may simply not mark his base function
 as nooverload. Let's say that the child is inheriting all the parent's
 methods because he wanted a different method (an already existing one),
 and the author of the parent class adds methodA (without the nooverload
 attribute) after the child is already written. That's an unintentional
 hijack. The problem is the child is relying on the parent to cooperate
 in preventing hijacking, instead of controlling whether its functions
 can be hijacked or not.

 In the current solution, the system warns me or throws an error if a
 function becomes hijacked. If this happens, I can examine the code and
 add an alias if needed. It happens rarely for me. Do you have cases
 where you have to "alias all over the place"? Maybe you are not doing
 something correctly, you shouldn't need this feature all the time.

 Note that drastic proposals like this are very unlikely to be accepted.
 Especially for something that has been in use and not really complained
 about for years. You need to present a very compelling argument,
 including real examples is helpful. Also, if there's any way to get rid
 of adding a keyword, you have a much better shot of success. No keywords
 have been added to the language for a long time.

 -Steve
Hi Steve, Please note that the proposal is not to remove the existing function hijacking detection but as an alternative to the existing aliasing.
OK, but I don't see the point then. Can't you get the functionality you desire already?
  >Consider how function hijacking happens. For instance, the parent  
  >class author may not even know his code is being overridden, and he  
  >may simply not mark his base function as nooverload.
  From OO stand point, overloading is NOT overriding.
 Please do not mix up the two. Fundamentally different.
Sorry, I used the wrong term, I meant derived or extended.
  >parent class adds methodA (without the nooverload attribute)
 If that happens, still flag as function hijacking using existing  
 detection. Please note that I did NOT ask for the removal of using
 aliasing on existing source code for inherited overloaded function.
Yes, but you marked the child as inheritall, doesn't this implicitly pull in the parent functions as if an alias were entered? Eseentially, the inheritall keyword disables all inheritance hijacking checks. Or did I misunderstand this?
 BTW, default D documentation is Not too friendly for inheritance tree  
 navigation. Unlike in java.
This is definitely a problem, ddoc is very underdeveloped. There are some alternative doc generators out there, I think Tango uses dil, which is a d-based compiler that does not yet generate code, but will generate docs (and much better docs at that). But let's not add features to cover up another problem that should be fixed in its own right.
 However, new keywords can be added to the compiler. So that future code
 can be written without spending many brain cycle on looking up such  
 alias. Let the compiler do the hard work of AST searching rather than
 a manual process. We have quad core now a days, even in asia.
The issue is not whether the compiler can search the AST, the issue is whether it makes functions easier to be hijacked.
 Have you systemetic go over the proposal I posted and gave your counter  
 arguement? How about the fact that currently there are such aliasing all  
 over the child class. From what I understand D inheritance is Not  
 automatic, if I am wrong do let me know.

 Do you have cases where you have to "alias all over the place"?
 news://news.digitalmars.com:119/iri4am$2dl3$1 digitalmars.com

 http://hg.dsource.org/projects/dwt2/file/d00e8db0a568/base/src/java/io/ByteArrayInputStream.d
Only read is required to be aliased, due to the base function read(byte[] b). All the others are unnecessary. I may see why you see so many cases -- dwt was likely ran through a java to d converter, and such converters often add unnecessary lines, because it is easier to do that than to examine each individual case. This further weakens your proposal in two ways: 1. The compiler does not need to foster to one small specific porting tool which does not generate optimal code. 2. Your argument is based on having to manually search for functions to alias, yet this tool clearly did all the aliasing for you. Essentially, your proposal makes it easier to make D inheritance rules more like Java ones, and I don't think we need such a feature. It's already possible to do this via alias, and D's stance is specifically *against* Java-style inheritance.
  >instead of controlling whether its functions can be hijacked or not.
 Why NOT? If a problem can be prevented easily as an modifier keyword.
 Hijacking is not a feature, it is a problem correct???
Anti-hijacking is a feature. Your proposal removes that when you use inheritall. -Steve
May 27 2011
next sibling parent reply Matthew Ong <ongbp yahoo.com> writes:
On 5/27/2011 8:08 PM, Steven Schveighoffer wrote:
 Sorry, I used the wrong term, I meant derived or extended.
Explain please. You lost me. If I am not wrong, final is used to prevent overriding. Is that what you are talking about?
 Yes, but you marked the child as inheritall, doesn't this implicitly
 pull in the parent functions as if an alias were entered? Eseentially,
 the inheritall keyword disables all inheritance hijacking checks. Or did
 I misunderstand this?
inheritall only to that single class and not from child to child and so on. Because of the nooverload keyword. There is a better way to further enhance that anti-hijacking proctection. It is a manually controlled approaches by developer of the child class.
 This is definitely a problem, ddoc is very underdeveloped. There are
 some alternative doc generators out there, I think Tango uses dil, which
 is a d-based compiler that does not yet generate code, but will generate
 docs (and much better docs at that).
Do both improvement. Please also support my post on: Example within documentations of D seriously need some improvement. Please place in the issue you see there compare to others languages already has.
 But let's not add features to cover up another problem that should be
 fixed in its own right.
NO. It is not a feature to cover up that problem. It prevents the same issue with less manual work.
 The issue is not whether the compiler can search the AST, the issue is
 whether it makes functions easier to be hijacked.
I believe the 2 feature does not make it easier to be hijacked. See above. Compiler can search the AST is key. Most source code development process needs to look at at least 7 different dimensions. Inheritance down the tree, up the tree, interfaces and its implementation, changes over time, testing, cpu cycle, memory creation cycle. That is just single threaded model.
 Only read is required to be aliased, due to the base function
 read(byte[] b). All the others are unnecessary.

 I may see why you see so many cases -- dwt was likely ran through a java
 to d converter, and such converters often add unnecessary lines, because
 it is easier to do that than to examine each individual case.
It does not seem to be because the dwt library has many different authors. If yes, please give some idea on how to do that via a converter.
 This further weakens your proposal in two ways:

 1. The compiler does not need to foster to one small specific porting
 tool which does not generate optimal code.
I am referring to manually written and naturally grown business library. I do agrees that a language is not design based on how a generated tool create its code.
 2. Your argument is based on having to manually search for functions to
 alias, yet this tool clearly did all the aliasing for you.
Yes. If and ONLY if you are doing auto java to D conversion. How about when the hand coded library grow?
 Essentially, your proposal makes it easier to make D inheritance rules
 more like Java ones, and I don't think we need such a feature. It's
 already possible to do this via alias, and D's stance is specifically
 *against* Java-style inheritance.
Yes. I can see some of the problem that might have from reading the unintentional function hijacking. That is why I am proposing the new keyword to make thing easier for people to inherit AND ALSO prevent highjacking.
instead of controlling whether its functions can be hijacked or not.
Why NOT? If a problem can be prevented easily as an modifier keyword. Hijacking is not a feature, it is a problem correct???
Anti-hijacking is a feature. Your proposal removes that when you use inheritall. -Steve
-- Matthew Ong email: ongbp yahoo.com
May 27 2011
parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Fri, 27 May 2011 08:36:08 -0400, Matthew Ong <ongbp yahoo.com> wrote:

 On 5/27/2011 8:08 PM, Steven Schveighoffer wrote:
 Sorry, I used the wrong term, I meant derived or extended.
Explain please. You lost me. If I am not wrong, final is used to prevent overriding. Is that what you are talking about?
No, I mean the author of Parent may not know of the existance of child, and its implementation of methodA. Let me walk you through a scenario. Author 1 implements Parent: class Parent { void methodB(int i) {...} } Author 2 wants to inherit from Parent, but he also wants to overload methodB, so he writes: class Child : Parent { void methodB(string s) {...} void methodA(long l) {...} } To allow one to call the parent's methodB, he uses your new keyword: class Child : inheritall Parent ... Now, sometime in the future, Author 1, without knowing about Author 2's derivation of his work, decides to add methodA which does something completely different from Child's implementation: class Parent { void methodB(int i) {...} void methodA(int i) {...} } Because Child is marked as inheritall, it compiles without complaint, and a call to childinstance.methodA(1) now calls the new Parent's methodA, when previously it called Child's methodA. This is a form of hijacking. Compare this to if you simply aliased methodB: class Child : Parent { alias Parent.methodB methodB; .... } Now, the hijacking introduced with methodA is properly disallowed, and calling methodA on the base throws a hidden function error.
 Yes, but you marked the child as inheritall, doesn't this implicitly
 pull in the parent functions as if an alias were entered? Eseentially,
 the inheritall keyword disables all inheritance hijacking checks. Or did
 I misunderstand this?
inheritall only to that single class and not from child to child and so on. Because of the nooverload keyword. There is a better way to further enhance that anti-hijacking proctection. It is a manually controlled approaches by developer of the child class.
Isn't nooverload supposed to be on the Parent class? How would Author 1 know about Child and know he should put nooverload on methodA when he adds it?
 This is definitely a problem, ddoc is very underdeveloped. There are
 some alternative doc generators out there, I think Tango uses dil, which
 is a d-based compiler that does not yet generate code, but will generate
 docs (and much better docs at that).
Do both improvement. Please also support my post on: Example within documentations of D seriously need some improvement. Please place in the issue you see there compare to others languages already has.
The poor navigability of DDoc generated documentation is not a new problem. It's been bad for years. It receives little attention because there are few people working on the compiler, and their time is spent improving the code generating features. I suspect someone else will have to step up in order to get ddoc to generate better docs. IMO the largest problem is that dmd is written in C++, and avoiding C++ is one of the main reasons many people are here ;)
 But let's not add features to cover up another problem that should be
 fixed in its own right.
NO. It is not a feature to cover up that problem. It prevents the same issue with less manual work.
I'm saying the poor navigability of DDoc documentation is not a justification for your proposal. It might be less manual work, but I would argue the manual work is minuscule to begin with.
 The issue is not whether the compiler can search the AST, the issue is
 whether it makes functions easier to be hijacked.
I believe the 2 feature does not make it easier to be hijacked. See above. Compiler can search the AST is key. Most source code development process needs to look at at least 7 different dimensions. Inheritance down the tree, up the tree, interfaces and its implementation, changes over time, testing, cpu cycle, memory creation cycle. That is just single threaded model.
It seems too easy to remove hijacking protection using inheritall. I don't think the nooverload keyword is necessary if inheritall doesn't exist, and it seems like something that would be rarely used. I just don't see enough simplification or improvements to justify allowing an easy off-switch for hijack protection. You should know, the very first post I made on this newsgroup (almost 4 years ago) was to complain about not overloading against base functions, and it lead to improved error detection (the hidden func exception), and the hijacking article being written. I think at this point, you have a 0% chance of getting Walter to change it. I don't want to discourage people from coming up with new and interesting ideas, but this one is not new.
 Only read is required to be aliased, due to the base function
 read(byte[] b). All the others are unnecessary.

 I may see why you see so many cases -- dwt was likely ran through a java
 to d converter, and such converters often add unnecessary lines, because
 it is easier to do that than to examine each individual case.
It does not seem to be because the dwt library has many different authors.
I'm not saying the entire code based is simply the output of a java converter, I'm saying the *aliases* are the result of the converter. I don't see why any person would waste the time to alias in all the base class' functions they are fully overriding, why wouldn't they just do the ones that are necessary? Looking again at the code, there is more evidence in the first line: /* language convertion www.dsource.org/project/tioport */ Note the url is incorrect, it should be: http://www.dsource.org/projects/tioport "The TioPort Project does Java to D conversion of whole libraries and applications."
 This further weakens your proposal in two ways:

 1. The compiler does not need to foster to one small specific porting
 tool which does not generate optimal code.
I am referring to manually written and naturally grown business library. I do agrees that a language is not design based on how a generated tool create its code.
A fully manually written code base would not contain so many aliases.
 2. Your argument is based on having to manually search for functions to
 alias, yet this tool clearly did all the aliasing for you.
Yes. If and ONLY if you are doing auto java to D conversion. How about when the hand coded library grow?
Then adding the occasional alias is good enough. -Steve
May 27 2011
prev sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2011-05-27 14:08, Steven Schveighoffer wrote:
 On Fri, 27 May 2011 07:42:17 -0400, Matthew Ong <ongbp yahoo.com> wrote:

 On 5/27/2011 7:08 PM, Steven Schveighoffer wrote:
 I don't think it will work that well. Consider how function hijacking
 happens. For instance, the parent class author may not even know his
 code is being overridden, and he may simply not mark his base function
 as nooverload. Let's say that the child is inheriting all the parent's
 methods because he wanted a different method (an already existing one),
 and the author of the parent class adds methodA (without the nooverload
 attribute) after the child is already written. That's an unintentional
 hijack. The problem is the child is relying on the parent to cooperate
 in preventing hijacking, instead of controlling whether its functions
 can be hijacked or not.

 In the current solution, the system warns me or throws an error if a
 function becomes hijacked. If this happens, I can examine the code and
 add an alias if needed. It happens rarely for me. Do you have cases
 where you have to "alias all over the place"? Maybe you are not doing
 something correctly, you shouldn't need this feature all the time.

 Note that drastic proposals like this are very unlikely to be accepted.
 Especially for something that has been in use and not really complained
 about for years. You need to present a very compelling argument,
 including real examples is helpful. Also, if there's any way to get rid
 of adding a keyword, you have a much better shot of success. No keywords
 have been added to the language for a long time.

 -Steve
Hi Steve, Please note that the proposal is not to remove the existing function hijacking detection but as an alternative to the existing aliasing.
OK, but I don't see the point then. Can't you get the functionality you desire already?
Consider how function hijacking happens. For instance, the parent
class author may not even know his code is being overridden, and he
may simply not mark his base function as nooverload.
From OO stand point, overloading is NOT overriding. Please do not mix up the two. Fundamentally different.
Sorry, I used the wrong term, I meant derived or extended.
parent class adds methodA (without the nooverload attribute)
If that happens, still flag as function hijacking using existing detection. Please note that I did NOT ask for the removal of using aliasing on existing source code for inherited overloaded function.
Yes, but you marked the child as inheritall, doesn't this implicitly pull in the parent functions as if an alias were entered? Eseentially, the inheritall keyword disables all inheritance hijacking checks. Or did I misunderstand this?
 BTW, default D documentation is Not too friendly for inheritance tree
 navigation. Unlike in java.
This is definitely a problem, ddoc is very underdeveloped. There are some alternative doc generators out there, I think Tango uses dil, which is a d-based compiler that does not yet generate code, but will generate docs (and much better docs at that). But let's not add features to cover up another problem that should be fixed in its own right.
 However, new keywords can be added to the compiler. So that future code
 can be written without spending many brain cycle on looking up such
 alias. Let the compiler do the hard work of AST searching rather than
 a manual process. We have quad core now a days, even in asia.
The issue is not whether the compiler can search the AST, the issue is whether it makes functions easier to be hijacked.
 Have you systemetic go over the proposal I posted and gave your
 counter arguement? How about the fact that currently there are such
 aliasing all over the child class. From what I understand D
 inheritance is Not automatic, if I am wrong do let me know.

 Do you have cases where you have to "alias all over the place"?
 news://news.digitalmars.com:119/iri4am$2dl3$1 digitalmars.com

 http://hg.dsource.org/projects/dwt2/file/d00e8db0a568/base/src/java/io/ByteArrayInputStream.d
Only read is required to be aliased, due to the base function read(byte[] b). All the others are unnecessary. I may see why you see so many cases -- dwt was likely ran through a java to d converter, and such converters often add unnecessary lines, because it is easier to do that than to examine each individual case.
DWT is manually ported from Java. A automatic port was tried and it didn't workout that well, too much of the Java standard library needed to be reimplemented in D. The port tries to stay as close to the original code base as possible to ease merging future versions of SWT and to minimize porting bugs. -- /Jacob Carlborg
May 27 2011
parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Fri, 27 May 2011 09:43:39 -0400, Jacob Carlborg <doob me.com> wrote:

 On 2011-05-27 14:08, Steven Schveighoffer wrote:
 I may see why you see so many cases -- dwt was likely ran through a java
 to d converter, and such converters often add unnecessary lines, because
 it is easier to do that than to examine each individual case.
DWT is manually ported from Java. A automatic port was tried and it didn't workout that well, too much of the Java standard library needed to be reimplemented in D. The port tries to stay as close to the original code base as possible to ease merging future versions of SWT and to minimize porting bugs.
Why is this comment in the file given? /* language convertion www.dsource.org/project/tioport */ Regardless of whether this was a manual port or not, the profuse aliasing is unnecessary, and does not provide a valid use case for the proposal. -Steve
May 27 2011
parent Jacob Carlborg <doob me.com> writes:
On 2011-05-27 16:09, Steven Schveighoffer wrote:
 On Fri, 27 May 2011 09:43:39 -0400, Jacob Carlborg <doob me.com> wrote:

 On 2011-05-27 14:08, Steven Schveighoffer wrote:
 I may see why you see so many cases -- dwt was likely ran through a java
 to d converter, and such converters often add unnecessary lines, because
 it is easier to do that than to examine each individual case.
DWT is manually ported from Java. A automatic port was tried and it didn't workout that well, too much of the Java standard library needed to be reimplemented in D. The port tries to stay as close to the original code base as possible to ease merging future versions of SWT and to minimize porting bugs.
Why is this comment in the file given? /* language convertion www.dsource.org/project/tioport */ Regardless of whether this was a manual port or not, the profuse aliasing is unnecessary, and does not provide a valid use case for the proposal. -Steve
I have no idea. The major part of DWT is manually ported, as far as I know. In this case it seems that not all of the aliases are necessary. But in general, in DWT, we want D to behave as Java, to ease porting. Just for the record, I'm not trying to argument for either anyone's side here, I'm just trying to correct facts about DWT that was incorrect. And apparently I was incorrect as well :) -- /Jacob Carlborg
May 27 2011
prev sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2011-05-27 13:42, Matthew Ong wrote:
 On 5/27/2011 7:08 PM, Steven Schveighoffer wrote:

 Do you have cases where you have to "alias all over the place"?
 news://news.digitalmars.com:119/iri4am$2dl3$1 digitalmars.com

 http://hg.dsource.org/projects/dwt2/file/d00e8db0a568/base/src/java/io/ByteArrayInputStream.d


  >Maybe you are not doing something correctly, you shouldn't need this
 feature all the time.
 Not me, others that has coded the dwt and I suspect other code in

DWT is a direct port of the Java library SWT and it tries to stay as close to the original code base as possible to easy merges of future release of SWT. When coding my own projects (projects I've written from scratch and not ported from other languages) it's a feature I rarely use, don't know if I ever have used it. -- /Jacob Carlborg
May 27 2011
parent reply Matthew Ong <ongbp yahoo.com> writes:
On 5/27/2011 9:37 PM, Jacob Carlborg wrote:
 On 2011-05-27 13:42, Matthew Ong wrote:
 On 5/27/2011 7:08 PM, Steven Schveighoffer wrote:
Maybe you are not doing something correctly, you shouldn't need this
feature all the time. Not me, others that has coded the dwt and I suspect other code in
 DWT is a direct port of the Java library SWT and it tries to stay as
 close to the original code base as possible to easy merges of future
 release of SWT.
No problem.I have not worked too much with SWT but people from development world told me they really do not like Swing. Yes. I agree because of the heavy/deep tree inheritance/too much manual copy/paste/undo sort handling. Different topic.
DWT is manually ported from Java. A automatic port was tried and it 
didn't workout that well, too much of the Java standard library needed 
to be reimplemented in D.
Yes. I notice that and notice that the language converter does not work that well because of the semantics of differences in the languages. Not impossible, but too heavy. Unless something like JRuby(JVM) and also IronRuby(.NET) is done and made use of the existing script engine extensions with existing API libray.
 When coding my own projects (projects I've written from scratch and not
 ported from other languages) it's a feature I rarely use, don't know if
 I ever have used it.
Actually from scratch is NOT a good approach and migration approach. How do you justify this to business management people or to your client? There are also your learning cycle time. Using Java well know Model-View-Controller as a simple model as a discussion. See: http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller Model= Business Data/IO/Persistance storage Controller= Business Logic and where transaction code are done. View= GUI/Web/Webservices(I am aware webservice is not a view)/Console. Interconnection = how all the MVC are interacting with each other. Those arrow in the diagram top right. Model and Controller typically are similar if not identical across different languages and platform. Most people would just do as much POJO(Plain Old Java Object) as possible here. However when it comes to the View and Interconnection...Those typically changed when moving into different platform. Unless there is someone that port them. Nothing much can be done here.
it's a feature I rarely use, don't know if I ever have used it.
Because of many years of object-relational database management system (ORDBMS). Most Database table even the flat one like Mysql are design with this concept in mind. Hence, the Model and Controller will have plenty of inheritance tree and mutually dependent code. That would mean alias would be used. If porting SWT has already such syntax and scatted aliases, that would be the burden that coder would have to take on, may I stress, could have been taken over my compiler with new sets of keyword. -- Matthew Ong email: ongbp yahoo.com
May 27 2011
parent reply Jacob Carlborg <doob me.com> writes:
On 2011-05-27 16:38, Matthew Ong wrote:
 On 5/27/2011 9:37 PM, Jacob Carlborg wrote:
 On 2011-05-27 13:42, Matthew Ong wrote:
 On 5/27/2011 7:08 PM, Steven Schveighoffer wrote:
Maybe you are not doing something correctly, you shouldn't need this
feature all the time. Not me, others that has coded the dwt and I suspect other code in
 DWT is a direct port of the Java library SWT and it tries to stay as
 close to the original code base as possible to easy merges of future
 release of SWT.
No problem.I have not worked too much with SWT but people from development world told me they really do not like Swing. Yes. I agree because of the heavy/deep tree inheritance/too much manual copy/paste/undo sort handling. Different topic. >DWT is manually ported from Java. A automatic port was tried and it >didn't workout that well, too much of the Java standard library needed >to be reimplemented in D. Yes. I notice that and notice that the language converter does not work that well because of the semantics of differences in the languages. Not impossible, but too heavy. Unless something like JRuby(JVM) and also IronRuby(.NET) is done and made use of the existing script engine extensions with existing API libray.
 When coding my own projects (projects I've written from scratch and not
 ported from other languages) it's a feature I rarely use, don't know if
 I ever have used it.
Actually from scratch is NOT a good approach and migration approach. How do you justify this to business management people or to your client? There are also your learning cycle time.
Of course, from "scratch" can be interpreted in different ways. I use the standard library and other libraries I need. But often when developing tools for D one can't use already existing tools because they don't support D or, in my opinion, aren't good enough. BWT, I don't have to justify my own private projects to anyone. One last thing: what's wrong with developing something from scratch just for the fun of it or for learning something from it :)
 Using Java well know Model-View-Controller as a simple model as a
 discussion. See:
 http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller

 Model= Business Data/IO/Persistance storage
 Controller= Business Logic and where transaction code are done.
 View= GUI/Web/Webservices(I am aware webservice is not a view)/Console.
 Interconnection = how all the MVC are interacting with each other. Those
 arrow in the diagram top right.

 Model and Controller typically are similar if not identical across
 different languages and platform. Most people would just do as much
 POJO(Plain Old Java Object) as possible here.

 However when it comes to the View and Interconnection...Those typically
 changed when moving into different platform. Unless there is someone
 that port them. Nothing much can be done here.
I'm working with the MVC design pattern every day at work (Ruby on Rails).
  >it's a feature I rarely use, don't know if I ever have used it.
 Because of many years of object-relational database management system
 (ORDBMS). Most Database table even the flat one like Mysql are design
 with this concept in mind. Hence, the Model and Controller will have
 plenty of inheritance tree and mutually dependent code. That would mean
 alias would be used.
As I said above: I'm using the MVC design pattern every day at work with Ruby on Rails which has, in my opinion, a great ORM library. It's not very often I create a class hierarchy of the models. Bacially the only hierarchy that exists is inheriting form the framework classes but when separating the framework from the user code there's basically no hierarchy in the user code.
 If porting SWT has already such syntax and scatted aliases, that would
 be the burden that coder would have to take on, may I stress, could have
 been taken over my compiler with new sets of keyword.
I can tell you this: after porting (almost) the whole SWT Mac OS X version to D I haven't seen this as a problem. Just inserting a few aliases and the problem is solved. -- /Jacob Carlborg
May 27 2011
parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On 2011-05-27 12:27, Jacob Carlborg wrote:
 On 2011-05-27 16:38, Matthew Ong wrote:
 On 5/27/2011 9:37 PM, Jacob Carlborg wrote:
 When coding my own projects (projects I've written from scratch and not
 ported from other languages) it's a feature I rarely use, don't know if
 I ever have used it.
Actually from scratch is NOT a good approach and migration approach. How do you justify this to business management people or to your client? There are also your learning cycle time.
Of course, from "scratch" can be interpreted in different ways. I use the standard library and other libraries I need. But often when developing tools for D one can't use already existing tools because they don't support D or, in my opinion, aren't good enough. BWT, I don't have to justify my own private projects to anyone. One last thing: what's wrong with developing something from scratch just for the fun of it or for learning something from it :)
Whether reimplementing from scratch or doing a more direct port makes more sense depends entirely on what you're doing. And when it's a personal project that you're doing for fun, it's that much more subjective than it would be when working on a project for work. It's definitely best to use as much knowledge as can be gained from the original code as best as possible when porting it to another language, but whether the actual code should be directly ported or just the basic ideas is very much dependent on the code and the situation. Sometimes it would be just plain stupid to rewrite the code, and in others, directly porting it would be a bad move. I recently started on a port of Haskell's Parsec library to D, since I think that it's an absolutely fantastic parsing library. And being as how the original library is in Haskell (which you're _definitely_ not going to port directly to D) and how I wouldn't necessarily want to use whatever the original license is, it just plain makes more sense to take the basic ideas (and to some extent API) of the original and create a D version that applies those. Porting the code directly would make no sense. With something like DWT on the other hand, doing a direct port and thus minimizing the effort of porting changes to it later would make a lot more sense (particularly since Java is a lot closer to D than Haskell). But whether "writing it from scratch" or not is the best choice depends very much on the code, your situation, and your goals for the project. It's not a black and white choice. - Jonathan M Davis
May 27 2011
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 5/27/11 1:34 AM, Matthew Ong wrote:
 Hi All,

 Currently within D, to make use of a parent class method you have to do:
 class Parent{
 void methodA(int x){...}
 }

 class Child : Parent{
 // I understand that it has to do with preventing accidental hijacking
 alias Parent.methodA methodA;
 void methodA(long x){...}
 }

 void main(string[]){
 Child obj=new Child();
 obj.methodA(1); // expecting to call Child.methodA but calling
 Parent.methodA;
 }

 and also from this URL.
 http://www.digitalmars.com/d/2.0/function.html
 If, through implicit conversions to the base class, those other
 functions do get called, an std.HiddenFuncError exception is raised.
I can't believe this has fallen off the radar. There should be no std.HiddenFuncError. Such errors must ALL be detected during compilation. Andrei
May 27 2011
next sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Fri, 27 May 2011 10:10:25 -0400, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:

 On 5/27/11 1:34 AM, Matthew Ong wrote:
 Hi All,

 Currently within D, to make use of a parent class method you have to do:
 class Parent{
 void methodA(int x){...}
 }

 class Child : Parent{
 // I understand that it has to do with preventing accidental hijacking
 alias Parent.methodA methodA;
 void methodA(long x){...}
 }

 void main(string[]){
 Child obj=new Child();
 obj.methodA(1); // expecting to call Child.methodA but calling
 Parent.methodA;
 }

 and also from this URL.
 http://www.digitalmars.com/d/2.0/function.html
 If, through implicit conversions to the base class, those other
 functions do get called, an std.HiddenFuncError exception is raised.
I can't believe this has fallen off the radar. There should be no std.HiddenFuncError. Such errors must ALL be detected during compilation.
You have three options: 1. keep the base implementation in place. If someone casts to the base class, and calls the hidden function, it just works. 2. force the user to override *all* overloads of the base, or alias them in. 3. Throw the hidden function error. 1 is how D used to be. I think Walter has some good case for why it is undesirable. 2 is just annoying. Either you will just alias the base functions (resulting in possible hijacking) or you will implement stub functions that throw an exception. If you want to go this route, I'd rather just have default aliasing of base functions. 2 is the only way to have a "compile" error. It is impossible to statically check if a function using a base class is actually using a derived class that hides the function being called. That is, you can only statically disallow the compilation of the derived class, not the hidden function call. Personally, I think the current implementation (item 3) is the least annoying. -Steve
May 27 2011
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 5/27/11 9:26 AM, Steven Schveighoffer wrote:
 On Fri, 27 May 2011 10:10:25 -0400, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:

 On 5/27/11 1:34 AM, Matthew Ong wrote:
 Hi All,

 Currently within D, to make use of a parent class method you have to do:
 class Parent{
 void methodA(int x){...}
 }

 class Child : Parent{
 // I understand that it has to do with preventing accidental hijacking
 alias Parent.methodA methodA;
 void methodA(long x){...}
 }

 void main(string[]){
 Child obj=new Child();
 obj.methodA(1); // expecting to call Child.methodA but calling
 Parent.methodA;
 }

 and also from this URL.
 http://www.digitalmars.com/d/2.0/function.html
 If, through implicit conversions to the base class, those other
 functions do get called, an std.HiddenFuncError exception is raised.
I can't believe this has fallen off the radar. There should be no std.HiddenFuncError. Such errors must ALL be detected during compilation.
You have three options: 1. keep the base implementation in place. If someone casts to the base class, and calls the hidden function, it just works. 2. force the user to override *all* overloads of the base, or alias them in. 3. Throw the hidden function error.
4. Statically disallow overloaded overridable methods when the parameters of one automatically convert to the parameters of another.
 1 is how D used to be. I think Walter has some good case for why it is
 undesirable.
 2 is just annoying. Either you will just alias the base functions
 (resulting in possible hijacking) or you will implement stub functions
 that throw an exception. If you want to go this route, I'd rather just
 have default aliasing of base functions.

 2 is the only way to have a "compile" error. It is impossible to
 statically check if a function using a base class is actually using a
 derived class that hides the function being called. That is, you can
 only statically disallow the compilation of the derived class, not the
 hidden function call.

 Personally, I think the current implementation (item 3) is the least
 annoying.

 -Steve
It is completely against the spirit of the language to decide that a call is resolved to an invalid method during runtime. There is no other feature remotely related to hiddenfunc. A couple of years ago, Walter gave a talk on hijacking to NWCPP. It all went well until HiddenFunc, at which point Walter's assertion that the way out was by throwing an exception was hotly debated. Several people suggested alternative, of whom one proposed (4) above. Everybody agreed it's a good solution, and Walter had the presence of mind and humility to acknowledge that solution and to promise to look into implementing it. Unfortunately, that event was forgotten... until now. Andrei
May 27 2011
next sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Fri, 27 May 2011 10:54:14 -0400, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:

 It is completely against the spirit of the language to decide that a  
 call is resolved to an invalid method during runtime. There is no other  
 feature remotely related to hiddenfunc.

 A couple of years ago, Walter gave a talk on hijacking to NWCPP. It all  
 went well until HiddenFunc, at which point Walter's assertion that the  
 way out was by throwing an exception was hotly debated. Several people  
 suggested alternative, of whom one proposed (4) above. Everybody agreed  
 it's a good solution, and Walter had the presence of mind and humility  
 to acknowledge that solution and to promise to look into implementing  
 it. Unfortunately, that event was forgotten... until now.
I just tried it out. If one implements an overload that is not contentious (for example, between int and string), no hidden func error is thrown. So indeed the compiler has a notion of when a function would be hijacked. I thought HiddenFuncError was thrown whenever you called any overloaded base method. So I agree with you, this needs to be fixed. Is there a bugzilla on it, or should we file one? Let's not lose it again. -Steve
May 27 2011
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 5/27/11 10:04 AM, Steven Schveighoffer wrote:
 On Fri, 27 May 2011 10:54:14 -0400, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:

 It is completely against the spirit of the language to decide that a
 call is resolved to an invalid method during runtime. There is no
 other feature remotely related to hiddenfunc.

 A couple of years ago, Walter gave a talk on hijacking to NWCPP. It
 all went well until HiddenFunc, at which point Walter's assertion that
 the way out was by throwing an exception was hotly debated. Several
 people suggested alternative, of whom one proposed (4) above.
 Everybody agreed it's a good solution, and Walter had the presence of
 mind and humility to acknowledge that solution and to promise to look
 into implementing it. Unfortunately, that event was forgotten... until
 now.
I just tried it out. If one implements an overload that is not contentious (for example, between int and string), no hidden func error is thrown. So indeed the compiler has a notion of when a function would be hijacked. I thought HiddenFuncError was thrown whenever you called any overloaded base method. So I agree with you, this needs to be fixed. Is there a bugzilla on it, or should we file one? Let's not lose it again. -Steve
Matthew's example fixed is this: class Parent{ void methodA(int x){} } class Child : Parent{ //alias Parent.methodA methodA; void methodA(long x){} } void main(string[]){ Parent obj = new Child(); obj.methodA(1); } The program throws with the alias commented out, doesn't throw with the alias. The desired behavior is to enforce three things: (a) "override" must be required everywhere overriding takes place (no warning, no debug mode etc); (b) if a class introduces a method with parameter types covariant with those of a homonym base method, it must introduce all overloads of that name (via alias or overriding); (c) if a class introduces two overloaded AND overridable methods, those must NOT have covariant parameters. (a) makes sure no undue overriding is ever present, (b) takes care of this example, and (c) takes care of the HiddenFunc examples given online at http://www.digitalmars.com/d/2.0/function.html. If you find the time, please make a bug report out of it and insert a link to this discussion in the report. Thanks much, Andrei
May 27 2011
prev sibling parent reply Dejan Lekic <dejan.lekic gmail.com> writes:
 A couple of years ago, Walter gave a talk on hijacking to NWCPP. It all
 went well until HiddenFunc, at which point Walter's assertion that the
 way out was by throwing an exception was hotly debated. Several people
 suggested alternative, of whom one proposed (4) above. Everybody agreed
 it's a good solution, and Walter had the presence of mind and humility
 to acknowledge that solution and to promise to look into implementing
 it. Unfortunately, that event was forgotten... until now.


 Andrei
Andrei, there was a discussion about it here on this NG too. I too think that (4) is definitely the best solution. At least that is what I would like D2 to do...
May 27 2011
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 5/27/11 1:06 PM, Dejan Lekic wrote:
 A couple of years ago, Walter gave a talk on hijacking to NWCPP. It all
 went well until HiddenFunc, at which point Walter's assertion that the
 way out was by throwing an exception was hotly debated. Several people
 suggested alternative, of whom one proposed (4) above. Everybody agreed
 it's a good solution, and Walter had the presence of mind and humility
 to acknowledge that solution and to promise to look into implementing
 it. Unfortunately, that event was forgotten... until now.


 Andrei
Andrei, there was a discussion about it here on this NG too. I too think that (4) is definitely the best solution. At least that is what I would like D2 to do...
Just talked to Walter - he did implement something similar that eliminates HiddenFunc, just only with -w. I ran a couple of tests and I find the behavior reasonable. (He does require introducing all overloads in derived classes, which is more permissive than what I had in mind but still eliminates HiddenFunc.) This is perhaps a good time to move these two -w features into the flag-free compiler: requiring override and detecting hidden functions during compilation. Andrei
May 27 2011
parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Fri, 27 May 2011 13:25:51 -0400, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:

 On 5/27/11 1:06 PM, Dejan Lekic wrote:
 A couple of years ago, Walter gave a talk on hijacking to NWCPP. It all
 went well until HiddenFunc, at which point Walter's assertion that the
 way out was by throwing an exception was hotly debated. Several people
 suggested alternative, of whom one proposed (4) above. Everybody agreed
 it's a good solution, and Walter had the presence of mind and humility
 to acknowledge that solution and to promise to look into implementing
 it. Unfortunately, that event was forgotten... until now.


 Andrei
Andrei, there was a discussion about it here on this NG too. I too think that (4) is definitely the best solution. At least that is what I would like D2 to do...
Just talked to Walter - he did implement something similar that eliminates HiddenFunc, just only with -w. I ran a couple of tests and I find the behavior reasonable. (He does require introducing all overloads in derived classes, which is more permissive than what I had in mind but still eliminates HiddenFunc.) This is perhaps a good time to move these two -w features into the flag-free compiler: requiring override and detecting hidden functions during compilation.
I think maybe this is a good thing for a bug report :) I'll make one. -Steve
May 27 2011
prev sibling parent Matthew Ong <ongbp yahoo.com> writes:
On 5/27/2011 10:10 PM, Andrei Alexandrescu wrote:
 On 5/27/11 1:34 AM, Matthew Ong wrote:
 Hi All,
At least not using foo and bar, I am able to understand some of that is being discussed here. Thank you all.
2 is just annoying.
For the sake of backward compatibility, keep that machination. How about the inheritall and nooverload pair? Or something like that, but different keyword or keyword pair. Could that be a way out of that state of annoyance and counter the spirit of inheritance. I am trying to show something like include-all/exclude-some filter like within a automatic list selections. But *please* make it easy to use and readable. Suggestions? -- Matthew Ong email: ongbp yahoo.com
May 27 2011