Mixins, C#, and Roslyn

Topics: C# Language Design
Apr 18 at 2:19 PM
Hi everybody,

I've been enamored by the idea of mixins in Ruby for a long time. Now that Roslyn is come around I feel it is the perfect time to experiment with the language. I wrote a post about mixins in C# and a possible implementation route but I have no idea how to proceed. So I have a few questions.
  • Are mixins inherently a bad idea or is it a good idea?
  • Is it possible to experiment with Roslyn and implement mixins in a fork
  • On a difficulty scale of 1 to 10, where does this implementation fall?
  • Does my theoretical implementation of mixins seem feasible or is it flawed
Here is a link to my post :) http://www.khalidabuhakmeh.com/roslyn-and-the-opportunity-for-mixins-in-c

I'd love to hear from the Roslyn team and whether you have ever considered mixins as an addition to the C# language. Any comments or thoughts would be appreciated. Also great work on open sourcing Roslyn and your continued contributions to .NET :)
Apr 18 at 4:11 PM
Have you considered the brittle base class problem? Inheritance in .Net has been carefully designed so that you can add a new method to the base class and all old code will still work the same.

How would that work with your mixins? What if you use two mixins in a class and one of them changes in a way that causes a conflict with the other mixin?
Apr 18 at 5:28 PM
hi @svick,

if there is code I'm sure there will be issues :) Let me address how I think conflicts should be resolved.
  • If a mixin has a method that has the same name but different parameters than another mixin we are good (likely to occur)
  • If a mixin has a property that matches another property in another mixin with the same type then they are considered the same thing
  • If a mixin has a property with the same name but a different type, then the last Mixin takes precedence and the other has to be accessed through casting. Compiler warnings are good here.
I'm not sure if you read my post or not, but to clarify. The Mixins in this case would just be syntactic sugar over the concept of interfaces in C#, with the addition of the compiler injecting code from mixin one and two. Interfaces already have ways to resolve conflict across interfaces and developers have to make those choices anyways right? Why would a mixin be any different than those situations?
    public interface IOne
    {
        string Name { get; set; }
        void Start();
    }

    public interface ITwo
    {
        string Name { get; set; }
        void Start();
    }

    public class SkipToMyLoo : IOne, ITwo
    {
        string IOne.Name { get; set; }
        string ITwo.Name { get; set; }

        void IOne.Start()
        {
            // code from Mixin One
        }

        void ITwo.Start()
        {
            // code from Mixin two
        }
    }
So to sum up:
  • Mixins are synactic sugar around existing interface structures
  • Conflict resolution already needs to occur for interfaces, why would mixins be different?
  • I am not talking about full-on multiple inheritance :) (I promise)
Does that clear up your question (I'm sure I just created a few more) :) ?

Also thanks for humoring me ;)
Apr 18 at 10:53 PM
If a mixin has a property that matches another property in another mixin with the same type then they are considered the same thing
What if the properties are not auto-properties, and have different implementations?
If a mixin has a property with the same name but a different type, then the last Mixin takes precedence and the other has to be accessed through casting.
That's exactly the problem: an innocuous addition to one mixin can significantly change the behavior of existing code. I believe the designers of C# are trying hard to avoid that.
Interfaces already have ways to resolve conflict across interfaces and developers have to make those choices anyways right? Why would a mixin be any different than those situations?
The situation with interfaces is different: when you add something to an interface, it's always a breaking change. But when you add something to a base class, it's going to work: there can't be any conflicts between two base classes and conflicts between the base class and the derived class are solved by preserving the old behavior when the base class changes.

And your mixins behave pretty much like base classes in this regard, so I think the expectation is that adding to a mixin shouldn't be a breaking change.
Apr 19 at 4:30 PM
mixins in C# (and VB) would be a new concept so the behavior could be anything we want it to be. We should focus on the why this might be a good idea and help developers be more productive :) If mixins in .NET behaved more like interfaces than base classes I would be completely fine with that. We make trade-offs all the time, but I think mixins would be a great addition to the language, even if there are potential downfalls.
That's exactly the problem: an innocuous addition to one mixin can significantly change the behavior of existing code. I believe the designers of C# are trying hard to avoid that.
To be fair to developers to everywhere, there is always a chance you are about to break something when you are adding new code to your solution. It shouldn't be a surprise. I've seen seemingly *innocuous code take down systems many times.

Without Mixin

public interface ICar {
  void Start();
}

public interface IGpsEnabled {
  Location Track();
}

public class AudiA4 : ICar, IGpsEnabled {
  public void Start() {
    // ... code
  }
  
  public Location Track() {
    // ... code
  }
}

public class WindowsPhone : IGpsEnabled {
  public Location Track() {
    // ... same code as Audi A4
  }
}

With Mixin

public mixin GpsEnabled {
  public Location Track() {
    // code
  }
}

public abstract class Car {
  public virtual Start() {
    // code
  }
}

public class AudiA4 : Car
  include: GpsEnabled { }

public class WindowsPhone 
 include : GpsEnabled { }
Would you not prefer the second option?
Developer
Apr 20 at 7:35 PM
Your idea sounds a lot like Scala traits as implemented on the Java virtual machine. It has come up only in passing in language design discussions. I personally think it is a good idea but it hasn't bubbled anywhere near the top of the list of things we'd like to do. This is definitely something you could do in a fork of Roslyn, but it is a pretty difficult task.