Implicitly implemented interfaces

WARNING: This is a speculative post. Caveat emptor.

This one is a little more speculative than the others, but it’s something that we’d like to get some feedback on. One complaint that we get from time to time has to do with interface implementation. A lot of people like the fact that there’s a nice explicit interface implementation syntax in VB, but sometimes it starts to feel, well, a little verbose. Even if you let the IDE create all the interface implementations for you, there’s still a lot of extra characters with all those “Implements IFoo.Bar”s, especially when the implementing method is the same name as the interface method.

One idea we’ve been kicking around is relaxing our rules to allow for implicit interface implementation. Today, when we’re checking interface implementation for some interface I1 what we do is:

  • Check to see if any base classes implement any of the members of I1. If so, we mark those methods as implemented.
  • Check to see if the current class implements any of the members of I1. If so, we mark those methods as implemented. If the current class implements a method that a base class implemented, the current class replaces that implementation.
  • If all of the methods of I1 are not implemented, we give an error.

What we would do is slightly modify the rules to:

  • Check to see if any base classes implement any of the members of I1. If so, we mark those methods as implemented.
  • Check to see if the current class implements any of the members of I1. If so, we mark those methods as implemented. If the current class implements a method that a base class implemented, the current class replaces that implementation.
  • If there are any methods of I1 that are not implemented, we check to see if there is a method with the same name and signature in the current class, and if there is, then that method implements the interface method.
  • If all of the methods of I1 are not implemented, we give an error.

What this would mean is that you could do something like this:

Class C1
    Implements IComparable(Of Integer)

    Public Function CompareTo(ByVal other As Integer) As Integer

    End Function
End Class

And not get any errors. There are a couple of things to note here if you’re familiar with C#, though. First, unlike in C#, if you declare a method in a derived class that has the same name as an interface method that is declared in a base class, you will still have to explicitly implement the interface method if you want the derived class method to take over. For example:

Class Derived
    Inherits Base
    Implements IComparable(Of Integer)

    ' Will not take over IComparable(Of Integer).CompareTo since Base already implements it!
    Public Function CompareTo(ByVal other As Integer) As Integer

    End Function
End Class

One could argue whether the derived class should or shouldn’t take over the implementation, but the bottom line is that if we allowed this we would be opening a potentially serious backwards compatibility problem. The above code could be written today (assuming Base implements IComparable(Of Integer)), and CompareTo will not take over the implementation of the interface. If recompiling your application in some future version of VB switched the implementation, this could introduce a very subtle and possibly very bad bug into your program. So it’s really a non-starter.

The other difference from C# is that we won’t search base classes for implicit interface implementations. For example, the following code would still give you an error:

Class Base
    Public Function CompareTo(ByVal other As Integer) As Integer

    End Function
End Class

Class Derived
    Inherits Base
    ' Error: IComparable(Of Integer).CompareTo is not implemented!
    Implements IComparable(Of Integer)
End Class

This can also be debated, but in the end we tend to err on the side of being more conservative-since Base didn’t implement IComparable(Of Integer) itself, it seems odd to pick it up when implementing the interface, as we have no way of knowing for sure that it’s really appropriate. There are also other highly technical issues relating to the mechanics of interface implementation that would make this situation complicated, especially if Base was in another assembly that we had no control over.

So the question is: would people find this useful? Annoying?

33 thoughts on “Implicitly implemented interfaces

  1. Scott Isaacs

    I wouldn’t be annoyed by it, but I don’t mind the way it is now either. Yes it is verbose now, but if you’re using Studio, it adds all the text for you so typing is not a big deal.

    One variation might be a change in Studio (more than in VB itself) such that if "CompareTo" already exists before I add "Implements IComparable" it prompts me to add the extra bits to the existing method definition (rather than assume it for me). Also, if two interfaces each have a like-named, like-signatured (??) members, it would be nice to be prompted to use the same implemenation for both.

    Reply
  2. Tim

    I don’t think i would utilize it but so as long as it doesnt step on my toes (ie. Vis Studio will still auto create the stubs upon pressing enter, which i find most useful) then by all means.

    It sounds like it is getting close to Duck typing, which i reckon would be awesome. I often have a problem where i inherit a class and override a few methods but sometimes i have the instance as the base class but want to use the overrided methods (i dont know if duck typing would help there or not, but it doesnt change how useful duck typing can be)

    For those that don’t know duck typing "If it looks like a duck and quacks like a duck, its a duck" so if an object looks like another one you can cast to it, i believe the Boo.net language implements duck typing.

    Reply
  3. Joe

    I would prefer to drop the implements altogether and enable pattern based type identity. So the compiler would need to test a type for compliance against an interface at runtime and dynamically flag the class as implementing the interface.

    This would make LINQ projection more powerful (I could implicitly cast a projection into an IEnumerable<INotifyPropertyChanged>) and it would make generic constraints easier to implement without impacting the parameter classes.

    Reply
  4. Ninputer

    I love this design so much! The Implements statement alwasy take more than 80 chars to write. It should only required when I want to change the implementation procedure name or visibility.

    Reply
  5. Steve

    Meh. Seems too loose. I think it would be common to have conflicts or ambiguousness so it is better to have the consistency of knowing you need to add the Implements.

    Not sure what the compiler tells you now — maybe it could suggest the thing to fixup — or in VS, suggest what is missing (like it does for import statements).

    If you must do it, then make it only do that when "Option Strict" is off. It just seems like something similar to not declaring variable types and loosey goosey casting.

    Reply
  6. Lamar

    I don’t mind this. but what I really want is the ability to take an interface with a read only property and implement it against a class’s property that has both a get and set without having to create a separate property for just the Get in order to implement the interface. I can do this in c#, but it doesn’t work in VB.

    Reply
  7. Bill McCarthy

    I hate it. You’d be breaking the contract that tells me implemented members are explicitly defined. That impacts on code maintenance. The IDE experience would also be screwy. You couldn’t hit enter and have the stubs generated for you anymore as that may not be what you want (especially if you do want implied to exisitng members)

    And because you are re-appropiating a keyword (or assignign a new behaviour to it) we have silly complex rules like only if the member is implied in this class not a base class will it be implied, which is bound to cause just as many headaches down the road.

    Why not simply have a different keyword for different behaviour ?, eg:

    Class Foo

    Implies IComparable(Of Integer)

    Then when people see that, they know that the implementation is implied and won’t have explicit declarations on it, and you can remove that need to limit it to only the current class and no base class members.

    Clear, unambiguous, and no silly false limitations as you try to work around breaking exisitng code as you re-appropaite an exisitng keyword.

    Reply
  8. Pingback: @ Head

  9. Branco Medeiros

    The idea per se is great, the problem is that it breaks so much a behavior already established in coding VB.Net.

    Maybe an attribute?

    Class SomeClass

    Implements <Implicit> IComparable(Of Integer)

    Public Function CompareTo(Other As Integer) As Integer

    ‘…

    End Function

    ‘…

    End Class

    Reply
  10. simon geering

    I think this, as with a number of the ideas in the recent speculative posts, is a great idea but not something for the language / compiler teams to be coding. This is something that should be built into the VS IDE i.e the IDE will automatically add the verbose implements text into the code file. This would give you the best of both worlds; it would still be obvious from a printed page of code what was going on but you wouldn’t need to type so much.

    Reply
  11. Morgan

    I don’t like implicit implemented interfaces in C# and I dont want to see it in VB either. It makes things unclear, which methods belong to which interface (if any).

    Reply
  12. Pingback: Jason Haley

  13. Anthony D. Green

    Wow, that got shot down pretty hard. I actually like this idea. I’d definitely rate Auto-Implemented Properties of much, much higher priority though. This does set a dangerous precedent that leads us back to Button1_Click style event handlers (I don’t want to go there). The concerns I have that would lead me to support this could be addressed by stronger editor support like smarter Intellisense and Refactorings.

    It would be helpful in generation scenarios to be able to add/remove an Implements statement to one partial class without breaking the entire thing. As it is if you want to add or remove an Implements statement you have to add/remove the Implements tag on all the members for it to work. This is just as important anytime you have high volatility your API (like when the project starts). This kind of thing enables developers to write better code more easily. The current interface implementation is great -initially- because VS will stub things out. Through development the actual interface may change and grow – when that happens I have to coax the editor into re-injecting the stub for just that member which can cause other problems if the interface inherits another interface. This is really an issue of commensurate effort. I don’t mind the extra work to bind a method body because they tend to be complex enough on their own. For properties (as they are now) it’s just adding insult to injury; I have some quick property code snippets but they don’t include an Implements modifier. With auto-props and better Intellisense I could get over it.

    Smarter Developer Interaction (Don’t ask what can reasonably be inferred).

    Less Lexical Noise (Don’t make me declare the obvious – see above).

    Auto-Implemented Properties + Implicitly Implemented Interfaces = RAD

    P.S. Paul: Since we’re on the road to Oz already – how about covariance/contra variance on interface implementations (explicitly of course); Why can’t Function Clone() As Customer Implement ICloneable.Clone – is a Customer not an Object?

    Reply
  14. paulvick

    One thing I didn’t say was that I think that if we did decide to do this, we would need to add a companion IDE feature that would allow you to "see" the implicit interface implementations. I’m not sure exactly what it would look like, but I would expect that people would still want to have some sort of indication that a method was being used to implicitly implement an interface, plus the ability to see which ones. This sounds like it might address some of the concerns.

    There are a few reasons why the proposal doesn’t include a new keyword or new syntax:

    * We’re not really introducing a new concept, so why are we introducing a new keyword? To take Bill’s suggestion, what’s *really* the difference between "Implementing" an interface and "Implying" it? It’s the same thing, but now I have to explain to someone new to VB the difference and they have to keep it in their head.

    * There are not-uncommon situations (IEnumerable(Of T) comes to mind) where you want to mix and match implicit and explicit implementation.

    And variance on implementation would be cool, it’s something we can look at!

    Reply
  15. Pingback: @ Head

  16. Bill McCarthy

    > To take Bill’s suggestion, what’s *really* the

    > difference between "Implementing" an interface

    > and "Implying" it?

    Interfaces can be explicitly implemented using the Implements keyword or implied by using the Implies keyowrd. When using the Implents keyword, you declre the class to Implement the interface and each member of the interface implemented in the class is denoted with the Implements phrase designating which member it maps to. Implements allows for mapping of interfaces to members with a different name (and potentially when we have variance, a different signature as well !)

    Implies on the other hand requires no modification of the members as they are matched by name and signature implicitly. And as per section 12.2 of the CLI, that matching *includes* base classes.

    http://msmvps.com/blogs/bill/archive/2008/04/09/more-on-implied-interfaces.aspx

    I’d also say that with variance on implementation, I’d only allow that with explicit Implements statements. I think having implicit interfaces with variance is a recipe for confusion. Plus, this maps well to the CLI specification, becuase an implied member must match by name and *signature*.

    Re: IEnumerable(Of T), I’d expect to be able to implement IEnumerable explicitly and the members defined in IEnumerable(Of T) implicitly.

    Ths is in fact the only time I know of when you need to use explicit interfcae mapping in VB is due to signature clashes, and those clashes only occur in interfaces which themselves inherit other interfaces with members of the same name.

    The important thing here is which would be clearer ?

    But then again, if we look at IEnumerable(Of T), the best thing there is variance on the implementation !

    Reply
  17. Raj Chaudhuri

    Another vote for "annoying". I feel that the explicit interface implementation in VB results in code that is much more maintainable than the alternative. Even with the IDE enhancements that Paul proposes, I feel that readability will take a hit.

    I liked Mr. McCarthy’s idea of a distinct "Implies" compiler behaviour at first sight. Thinking about it again, I think it might introduce a new set of problems. I vote to keep status quo on this one.

    Reply
  18. Justin Michel

    I don’t like the proposal, because I think there is a simpler solution that is more consistent with a related aspect of VB.

    The Implements keyword could be used analogously to the Overrides keyword.

    Just as ….

    MustInherit Class A

    MustOverride Sub Foo()

    End Class

    Class B

    Inherits A

    Public Overrides Sub Foo

    End Sub

    End Class

    you could support…

    Interface A

    Sub Foo

    End Interface

    Class B

    Implements A

    Public Implements Sub Foo()

    End Sub

    End Class

    I think you should also be able to support a more verbose syntax like:

    Public Implements Sub A.Foo()

    and even the existing

    Public Sub Bar() Implements A.Foo

    The existing verbose syntax would then only be useful when you want to change the name of the implementing Sub.

    Of course you *could* just combine all this with your original proposal, but then I would expect to be able to leave out "Overrides" keywords as well.

    Reply
  19. Tim Patrick

    I vote no on this suggested change. As other posters already said, it makes for code that is less than clear. So much code is already passed down to new programmers without comments or documentation, and with intricate logic left unexplained. Anything that makes such practices easier should be avoided.

    But beyond that, this post makes me wonder when the meaning of "RAD" changed in VB from "the complex made simple" to "requires fewer keystrokes."

    Reply
  20. Jonathan Allen

    I like Justin Michel’s suggestion. It clears up a lot of the clutter without adding complexity in terms of trying to figure out how a given interface is implemented.

    Reply
  21. Jonathan Allen

    > If there are any methods of I1 that are not implemented, we check to see if there is a method with the same name and signature in the current class, and if there is, then that method implements the interface method.

    I don’t like that idea. If I decide to move something to a base class, it would break my interfaces and we are right back to where we started.

    While I am torn about this proposal, I don’t want it to be half way. The compiler should either consider the entire inheritance hierarchy or leave everything as explicit.

    Reply
  22. russ

    I hate the way C# does interfaces because it makes it a huge pain to figure out where a method is getting implemented. This idea would just make it that much worse.

    Another vote here for Justin’s suggestion:

    Public Implements Sub Foo()

    Public Implements Sub A.Foo()

    Either one or both work great to reduce verbosity, and have the bonus side-effect of moving the indication that a method is an interface implementation closer to the left of the screen, which is always a good thing in terms of the IDE.

    I would also like to see this extended to the event handling, another great VB feature I miss in C#:

    Instead of this, where we specify the button twice:

    Public Sub Button1_OnClick(ByVal sender as object, ByVal e as EventArgs) Handles Button1.Click

    The alternate syntax could allow this (where the compiler creates a method named Button1_OnClick):

    Public Handles Sub Button1.Click(ByVal sender as object, ByVal e as EventArgs)

    Notice how we gain the same readability advantages as implementing an interface, with the bonus that we don’t specify the name of the event raiser twice (in the name of the method and in the Handles clause).

    Obviously it doesn’t work for a handler that deals with multiple senders/events, but you’ve got the handles clause on the right for that, if needed.

    Reply
  23. Bill McCarthy

    Re:

    Public Implements Sub A.Foo()

    That doesn’t actually gain us any functionality, just provides a different way of writing what we write today. As such, having multiple ways of doing the same exact thing is usually a bad thing to add to a language… it just adds complexity. A naming patter such as A.Foo is similar to explicit implementation in C#, and has the same drawbacks that the method cannot be called directly, rather a cast to the interface has ot be made, which for value types means boxing as well.

    But the real issue here is implied interfaces. Think for example when the member is generated for you by designer code where you cannot mark the method as Implements. And also consider when the method is in the base class. Today you can work around these things using a private implementation but that’s a lot of extra code. It’s this that implied itnerfaces should address.

    Reply
  24. Pingback: ??????

  25. Roman

    No, I don’t like it. It’s not too annoying as it is, and introducing implicit behavior may introduce subtle errors.

    Also:

    "If all of the methods of I1 are not implemented, we give an error."

    You might want to change this to "If not all of the methods of I1 are implemented, we give an error.".

    8=]

    Reply
  26. Jonathan Allen

    Ok Bill, you sold me. Having a better way to deal with those code-generated classes is more than enough to make up for any potential confusion.

    But as I said before, no half-way implementations. It needs to walk the entire inheritance tree.

    Reply
  27. Eric Mutta

    Paul:> A lot of people like the fact that there’s a nice explicit interface implementation syntax in VB, but sometimes it starts to feel, well, a little verbose.

    But Paul, "a little verbose" is something that VB lovers actually *like* – it’s where VB gets its simplicity/clarity feel from (e.g "inherits" is gazillions times better than ":").

    Also given that VS2K8 FINALLY has autocomplete for language keywords, these verbosity issues become non-issues.

    I vote "no" for this suggestion (and an emphatic "yes" for auto properties) because its takes a lexical problem and opens a whole can of rotten semantic issues.

    Personally, I wish the interface implementation syntax were as follows:

    Public Class CFoo

    Implements IFace

    Private Sub IFace.Baz()

    End Sub

    End Class

    …or failing that, I wish the Rename refactoring could be configured to change the implementing method name when the corresponding interface member’s name is changed.

    In closing, the single biggest change you can make to address any verbosity is to improve the code editor. If you add commands Select/Cut/Copy/Delete/MoveUp/MoveDown/Swap that operated on syntactic and lexical "arguments" like word/line/expression/statement/block that would change the game entirely. Add RepeatLastCommandNTimes and life becomes truly RSI-free!

    Reply
  28. Ivan Gusev

    I think that with autocompletion this feature is not very useful (still it’s better that what is now).

    It would be better if you spent more time on implementing anonymous delegates 🙂

    Reply
  29. David Nelson

    I vote no. I am primarily a C# programmer, but there are a number of things about VB.NET that I like better than C#, and this is one of them. Implicit interface implementation in C# is fragile and reduces readability. I like being able to look at a method definition and know whether or not it is being used as an interface implementation, without having to search for explicit interface implementations.

    @Bill,

    I recognize that code generation is becoming more and more common, but most of the VB.NET code being used in production applications is NOT generated, and I am confident that will continue to be the case for a long time. Compromising the design of the language to cater to code generation is one of the worst mistakes a language designer can make (the existence of "partial methods" will haunt us forever).

    Reply
  30. hans

    Implicit interface implementation is nothing but a source of error and confusion. It should never be allowed in VB.
    However there is one situation where explicit implemenation is quite awkward:
    If an interface should partially be implemented by the class, and partially by its base class. You have to implement all interface members in the class and map some of them to the base class. This, I suspect, has also a performance penalty at runtime.
    Example:

    Public Shadows ReadOnly Property Count() As Integer Implements ICollection.Count
    Get
    Return MyBase.Count
    End Get
    End Property

    If an Event is defined in the interface, it gets even uglier, because you have to write code to map the AddHandler, RemoveHandler and RaiseEvent methods.
    Instead I would like to suggest a new key word “MapsToBase”. Example:

    Public ReadOnly Property Count() As Integer Implements ICollection.Count MapsToBase
    ‘No code allowed here
    End Property

    Maybe the syntax could even ommit the “End Property”.

    Reply
  31. hans

    Two more syntax alternatives for the base class issue would be:

    Public ReadOnly Property MyBase.Count() As Integer Implements ICollection.Count

    or

    Public ReadOnly Property Number() As Integer Implements ICollection.Count MapsTo MyBase.Count

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *