Hi,
I was asked to highlight on the reflector an issue with the Interface Class proposal (mantis item 1356). The proposal calls for allowing an interface class to extend (inherit from) multiple interface classes. Whenever there is multiple inheritance there is the possibility of name collisions and the Interface Class proposal doesn't discuss how to resolve any such conflicts. We talked about this briefly at the May 23 SV-EC meeting. These are the main options that we discussed:
1) Don't allow any inheritance at all. The BNF would change so that an interface class would implement one or more interface classes, rather than extend one or more interface classes. Any references to parameters or typedefs from a "super" interface class would have to be scoped.
2) Whenever there is a conflict, the conflicting symbol is not inherited. Any reference to a symbol that has a conflict would therefore result in an elaboration error that the symbol was never defined or not found. This option is similar to the behavior in Java (I've looked it up) where any un-scoped reference to a symbol that is present in multiple super interfaces would be "considered ambiguous".
a. For further discussion on this option, would we allow inheritance if the conflicting symbol can be statically determined to resolve to the exact same value/type for all super interface classes? (Java would still consider that to be ambiguous).
3) Define a precedence. This can be done in two ways:
a. Allow an Interface Class to extend (inherit from) only one other interface class, and "implements" one or more interface classes for which there would be no inheritance.
b. Precedence of inheritance would be given by the order by which interface classes are inherited.
My take on each of the above (none of which is ideal):
1) This adds verbosity to code for the most common cases and it's not consistent with Java interfaces that we are modeling which will be confusing to those familiar with Java. Since all symbols will have to be scoped, this would result in code that is the most difficult to break.
2) This is most consistent with Java's behavior and it's less verbose than #1. When an error occurs it could be difficult to figure out why a symbol isn't found. A similar error in Java would tell you that the symbol is ambiguous and suggest what you might be referring to which would make it easier to fix. By "not inheriting" the symbol, the compiler/elaborator would just tell you that the symbol was not defined or not found, which isn't helpful. Users would still be free to act like nothing is inherited and refer to everything with a scope if they want.
a. This would reduce the verbosity and errors further, but I'm not entirely convinced that the ROI is there considering the extra effort on the tool side. Also, you are more likely to get apparently random errors where one usage of a parameterized interface class will give you errors, but another will not.
3) There are different problems with each choice.
a. This syntax is more confusing than the other options. Users would be prone to get errors where they intend to extend a single interface class but instead us the "implements" key word. Also, if you want to inherit from multiple interface you'd have to pick just one to extend.
b. This can lead to difficult to debug compile-time and run-time errors if you think that you are inheriting a symbol ICA::foo, but instead are inheriting ICB::foo and they are not the same.
I don't think that there is an ideal option, but we need to pick one of the above. Are there any thoughts from the committee?
Thanks,
Brandon
-- This message has been scanned for viruses and dangerous content by MailScanner, and is believed to be clean.Received on Tue May 31 15:31:20 2011
This archive was generated by hypermail 2.1.8 : Tue May 31 2011 - 15:31:23 PDT