C# 4, part 2: Ideas from other community members

There has been a fair amount of speculation online about what should be in C# 4. I’ve taken the list below from a few posts, primarily those by Ayende and Jeremy Miller. I’ve deliberately left out the ideas that Microsoft have mentioned that they’re at least considering – they’ll come in the next post.

Mixins

I suspect everyone has a different idea of what these mean, but I’ll say what I’d like. I want to be able to implement an interface by proxying all calls (other than those I’ve actually implemented) to a particular member variable, as an aid to favouring composition over inheritance. As an example, here’s a class which implements IList<string> but makes sure that only strings with length 5 or more can be added:

 

public class LongStringList : IList<string>
{
    [MixinImplementation(typeof(IList<string>))]
    readonly IList<string> m_list = new List<string>();

    public void Add(string item)
    {
        if (item.Length < 5)
        {
            throw new ArgumentException(“Only strings of length >= 5 allowed”);
        }

        m_list.Add(item);
    }
}

 

(Yes, you’d need to implement the setter as well to prevent other values being replaced. This is just sample code to give the rough flavour – and the syntax is pretty much made up as an example too. I’m not hung up on the syntax, I just want the functionality.

You could of course derive from System.ObjectModel.Collection<string> – but this prevents you from deriving from any other class, and fixes the inheritance forever. If you only really want to provide your clients with an IList<string> implementation, it’s nicer not to pin anything down. At a later date you could manually implement more of the interface members instead of proxying them, without changing any of the calling code.

Symbols

I don’t see the benefit over normal string interning here. That could just be because of a poor description of symbols in Ruby, admittedly… but I suspect any other benefit wouldn’t meet the “it’s got to be really useful in many situations” bar.

Hashes

I’ve only extensively used one language with hashes built in: Groovy. While I agree it’s nice occasionally, I don’t think it’s worth bending the language out of shape for as we’ve now got collection initializers anyway:

 

var hash = new Dictionary<string,int>
{
    { “First”, 1 },
    { “Second”, 2}
};

Automatic delegation

To be honest I don’t really know what Jeremy means here – although it’s possible that he means what I understand as mixins. Ah the joys of loose terminology.

Metaprogramming

I only have vague ideas of what metaprogramming is all about, and those are mostly through Ayende’s blog. I can see that it’s almost certainly very powerful, but I’m not sure I want it in C#. I don’t want C# to turn into a massive box with every nifty feature ever considered. It’s possible I could be turned on this one, if someone showed me it working really nicely.

Macros

Ick, no. I’ve seen what macros tend to be used for. I’m sure there are nice shiny reasons for them, but certainly in the C/C++ form I’d be heavily against them.

Update: Ian Griffiths mailed me drawing my attention to LISP macros and how different they are to C/C++ macros. The way Ian described it sounds similar to what I understand of the metaprogramming that Ayende wants to do. I can see why it’s a powerful tool… but personally I think I’d rather keep it away from a mainstream language like C#. I’ll be writing another blog post to explain my view on this, because it’s worthy of a much fuller discussion.

Everything virtual by default

Absolutely not! Yes, it would make mocking easier – but then making everything public by default would probably make things easier too. Inheritance is hard to control properly, and should only be done with very careful design. As I wrote in the previous post, I’d prefer classes to be sealed by default, i.e. a step in the opposite direction. Oh, there’s the performance implication too, which is one of the reason’s Java needs a much more complicated multi-pass JIT – to allow even virtual methods to be inlined until they’re actually overridden. The performance part is much, much less important than the “inheritance is powerful but easy to misuse” argument.

Not only should the default not change at this point, but it was the right default to start with.

Instant Data Type

This would basically be a way of using anonymous types at a higher level – returning them with a return type of var, for instance. I don’t support that proposal per se, but I can see a benefit in having “named anonymous types” – classes which have the same behaviour as anonymous types (in terms of immutability, equality, hash codes etc) but in a named manner. Something like this:

 

public class Person = new {string Name, DateTime DateOfBirth}

Person p = new Person { Name = “Jon”, DateOfBirth = 19.June(1976) };
Person p2 = new Person { Name = “Jon”, DateOfBirth = 19.June(1976) };

Assert.IsTrue(p.Equals(p2));
Assert.AreEqual(p.GetHashCode(), p2.GetHashCode());
// etc

 

Again, the syntax isn’t terribly important to me – but the ability to define very simple immutable data objects is nice. It could also improve the readability of some LINQ code as you could make the meaning of the (currently anonymous) tuple clear in the name.

A few anticipated comebacks:

  1. Clash with object initializers: yes, it looks like it’s setting properties rather than passing them in as constructor arguments. That’s unfortunate, and maybe parentheses would be better than braces here. That would require named parameters though. (I’ll come onto those in another post!)
  2. Why not just refactor the anonymous type to a named type? ReSharper lets you do this! Indeed it does – but then you’ve got a complete class to maintain. Given a single line of code, I know the features of the Person class. I can add a new property (breaking existing uses, of course) without having to make sure I get the equality and hash code implementations right manually, etc. I prefer simplicity of language expression over just saving typing by using snippets etc – that’s why I like automatic properties.
  3. It can’t use quite the same implementation as anonymous types. Indeed, anonymous types are quite interesting in terms of the number of types actually generated in the IL, due to sharing of generics. I don’t think it would be a great loss in this case though.
  4. The use still isn’t as brief as with anonymous types, due to needing to specify the name. True, but unavoidable, I think.

MemberInfo (infoof)

I don’t think the C# team have actually stated that this is even potentially on the table, but one of the lovely things about having Eric Lippert as a tech reviewer for the book is I get to hear all kinds of anecdotes about what’s been considered before. Some of them will be on the book’s website in the notes section. In this case, I don’t think it’s a problem to reveal that the C# team have considered this before as an infoof operator (commonly pronounced “in-foof” of course).

I could go for this idea – it would certainly make reflection simpler in a number of cases.

Method Interception and IDynamicObject

I’ve lumped these two together as they’re similiar (in my view) – they’re leading down the road to a dynamic language. I can appreciate the benefits of dynamic languages, but that doesn’t mean I think every language ought to be dynamic. I’d pass on these two.

Static interfaces

I’m not entirely sure what Ayende means on this front, but I know I’ve seen a number of requests for the ability to declare that a type definitely has a given static method. Indeed, I’ve wanted it myself a few times. However, I’m not sure how I’d go about using it. Interfaces by their current nature are used when we’ve got an instance. We already know how to pass references etc around – but not types, other than as either type parameters or Type objects.

Now, having just written it I wonder whether that’s what Ayende means – if a type parameter is constrained to implement a particular interface, any static methods within that interface could be called using the type parameter. I can see the use in a few situations, but I’d need to be convinced that it was common enough to warrant a language change. The bar wouldn’t be too high for me on this one though, as I think we could use very natural syntax without having to make up anything significantly new.

Aspect-Oriented Programming

Ooh, tricky one. I’m definitely undecided on this. I can see benefits, but also drawbacks in terms of how obvious the flow of the code is, etc – all the normal objections.

I think I’d welcome additions to the framework and/or runtime to make AOP support simpler, but then leave it to IoC containers etc to actually implement, rather than embedding AOP directly in the language.

Design by Contract

There are parts of DbC that I’d really like to see in the language, or possibly as a language/framework mixture where the framework describes certain common attributes (invariants, non-null arguments etc) and then each compiler takes note of the same attributes. I would really, really like to get rid of having manually-written trivial argument checking in my code. I don’t think I’d immediately want to go as far as Spec# though, in terms of trying to deduce correctness. I wouldn’t like to say why, beyond unfamiliarity (which I know isn’t a good reason). Again, I could possibly be persuaded.

IDisposable implementation support

Good idea. It’s a pain to implement IDisposable properly – some help would be welcome. It would probably need to be flexible enough to allow the developer to say whether a finalizer was required or not, and possibly some other things – but in principle, I’m in favour.

Constructor inheritance

Aargh, no. Constructors effectively belong to the type rather than instances of the type, so they’re not inherited in the same way. They’re a bit like static members – and I know we can call static members as if they were inherited as normal (e.g. UnicodeEncoding.ASCII), but it’s generally a bad idea to do so in my view.

Also consider the lack of control. System.Object has a parameterless constructor – so should all types do so as well, given that they all inherit (directly or indirectly) from System.Object? What would new FileStream() really mean? I suppose one possibility would be to mark your type as intentionally inheriting constructors – which is all very well until the base class adds a new constructor you don’t want, and you don’t realise it until it’s too late. On this one the complexities and disadvantages outweigh the advantages for me.

“Const correctness”

I haven’t actually seen anyone asking for this specifically for C# 4, but it’s been a general feature request pretty much forever. Again, I can see the benefits but:

  1. I suspect it’s the kind of thing you really need to get right in V1.0 for it to be genuinely useful.
  2. I still haven’t seen an easy way to express “this is an immutable reference to a mutable list of immutable objects of a particular type”. Basically you need to express “constness” for every level down the composition hierarchy, which isn’t simple.

 

Conclusion

Just to wrap the above up, here are the above features in “yes, maybe, no” categorization (just for my own view, of course):

  • Yes: Mixins, instant data types, IDisposable implementation, design by contract (partial), infoof
  • Maybe: Automatic delegation, metaprogramming, static interfaces
  • No: Symbols, hashes, everything virtual by default, macros, constructor inheritance, AOP, method interception and IDynamicObject

Next time (which may be tonight if I’m feeling energetic) I’ll look at what Microsoft has hinted at.

18 thoughts on “C# 4, part 2: Ideas from other community members”

  1. I’ve asked for a new Operator, .? in Connect, to deal with null checking when accessing members of an object:

    https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=296616

    What you think about that?, I’ve found some support in Microsoft forums (http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2033762&SiteID=1) and channel 9.

    BTW: In Javaland are thinking about the same concept!! (http://www.javapolis.com/confluence/display/JP07/Whiteboard+results+-+Language+change) And is pretty popular given how conservative they are for any non trivial feature :)

  2. I’d love to see regular expression literals. I’m tired of typing “Regex noCancer=new Regex(“my bad ass regular expression that matches cures cancer”);”

  3. Definitely agree on the support for AOP & Design by Contract – if I could specify parameter validation during contract definitions that would save alot of time and provide more clarity.

    Do you really think implementing the dispose pattern is time consuming, I think a lot of developers don’t do any interop into the unmanaged environment – the nearest they get is having to use the ‘using’ pattern for disposing on pre-defined classes.

    Oh and adding macro support would definitely be ‘Jumping the shark’ – check out wikipedia for a definition.

  4. Regex literals: I guess I don’t use enough regular expressions for it to be a pain point for me, and I nearly always end up making them static readonly variables which are declared once at the top of the class and then just used.

    How many regular expressions do you tend to create in, say, a week?

    Jon

  5. Implementing the dispose pattern: you don’t have to be using interop for it to be necessary to implement IDisposable. Admittedly if you’re not directly handling any unmanaged resources you *could* just implement IDisposable directly, not bother with the Dispose(bool) pattern etc – but it would be quite nice to get the compiler to sort it all out. It’s certainly not a high priority for me, but as a cause of so much *potential* it’s a nice to have.

    Jon

  6. I guess I don’t use them terribly frequently, but if I end up using them in a project it tends to be very Regex heavy. I get these goofy projects from time to time that need some heavy text parsing. I guess this would fall into my “nice to have” list.

    I also end up with static readonly variables which makes it somewhat less painful. I think the better thing to come out of literals would just be the ide being aware of them and validating them before compile time. I’m just talking basic stuff like checking that you’ve closed all of your parenthesis, brackets, and braces. It would also be a great addition with extension methods to enable a little more casual usage:

    “Josh Bush”.IsMatch(/^Josh/);
    “Mixed Tabs and spaces”.Split(/\s+/);
    “Mixed Tabs and spaces”.Replace(/\s+/, “,”);

    It’s still small potatoes I know, but I still think it’s be nice to have.

  7. If “const correctness” wasn’t in the language from the beginning, I don’t foresee it being added mid-stream. I, personally, think const correctness is good. But, it’s an all-in-or-not-at-all feature. If you don’t get const correctness perfect it becomes a nightmare–which is one reason it wasn’t added to C#.

    I agree with your virtual by default comment. If it were in from day one it would be one thing, but that’s not something that can be changed and still call it C#.

    infoof, memberof, eventof, propertyof, methodof would all be great additions. The compiler knows that information at runtime, using reflect to get it slow…

    Design by contract is another biggy for me. I prefer to get as much design-intention in at compile time; this will go a long way toward that.

    What C++/CLI does with IDisposable would be nice…

    I think more support for aspect-oriented programming wouldn’t hurt; but C# isn’t AOP (it can do AOSD) and never will be. Much of AOP would create many changes to the CLR too–something that involves a lot of friction.

    Another request that seems to go around a bit is implicitly typed members (possibly just privates). I personally think it’s a very bad idea.

  8. - mixins / automatic delegation
    - AOP goes along with method interception / first-class dynamic proxy support
    - design by contract !!!

    Also, multiple inheritance!!! You could get IDisposable implementation support with this trivially with an abstract base class, but then you’ve blown your base class. I’ll allow that maybe you include syntax or other control to make sure some of the pitfalls are avoided. But it’s the right way to achieve some designs and should be part of the language.

  9. Olmo: Only just noticed your suggestion.

    Yup, I’ve come across this before in Groovy. I would imagine it could be particularly useful in conjunction with ?? as well.

    I’m certainly not averse to the idea :)

    Jon

  10. One scenario I’ve come across where I’ve wished for static interfaces was working with generics and type constraints.

    There are times when I’d like to be able to construct a generic class or method that requires certain static methods on the type. One simple example that comes to mind is a base implementation of a TypeConverter for a type that implements the usual Parse/TryParse methods.

    An overly trivial example, using some syntax I’m making up on the spot:

    public static interface IParseable
    {
    static T Parse(string value);
    }

    public static class Helpers
    {
    public T FromString(string value)
    where T : static IParseable

    {
    return T.Parse(value);
    }
    }

    This of course brings me to a related feature that would be really keen for this: implicit static interfacing or duck typing. That way, I could use the FromString method on types like int and anything else that happens to implement the interface methods, whether or not they explicitly implement the interface. I imagine that would require CLR changes though.

  11. Re Mixins: Here’s a C#3-based mixin-ish pattern you should already be familiar with:

    public class Foo: IMarkerInterface { }

    public static class IMarkerInterfaceImpl
    {
    public static void DoStuff() { … }
    }

    var foo = new Foo();
    foo.DoStuff();

    .. Yes, it’s technically a hack, but it provides a nice amount of fairly safe composibility. It doesn’t address mixing in pre-existing interfaces, so perhaps we should change the usage of “I” in this case with “Mx”:

    public class Foo: MxMarker { }

  12. Keith: Maybe I’m just being stupid, but I don’t see how that’s like a mixin at the moment. Could you give a fuller example?

  13. Notice the “ish”.

    The idea is that you create marker interfaces, and extensions on those interfaces that define the mixin behaviors. Then, classes become effectively composable.

    It’s certainly not a “mix-in” in the sense that the implementation itself exists within the target class. It’s a “mix-in” in the sense of being composed of blocks of pre-defined (possibly third-party) code simply by marking the class with an interface.

    However, to get the deeper, implementation-bound mix-in, it’s entirely feasible (read: I have code at home that does as much, or close enough to it) to create types in memory at run-time which implement classes according to whatever rule you could provide a builder for. So, if we were to create a builder that undersood how to interpret a MixIn recipie, and create code that lifted API living elsewhere, then you have this without changing the language.

    Then, you have:

    public interface IFoo: IBar, IBaz { }

    var fooBuilder = Builder.Create(new { { typeof(IBar), typeof(BarImpl) }, { typeof(IBaz), typeof(BazImpl) } });

    var foo = fooBuilder.GetInstance();

    foo.DoFooStuff();
    foo.DoBarStuff();

  14. I think he meant to write DoStuff as an extension method:

    public class Foo: IMarkerInterface { }

    public static class IMarkerInterfaceImpl

    {

    public static void DoStuff(this IMarkerInterface bar) { … }

    }

    var foo = new Foo();

    foo.DoStuff();

    That way, DoStuff could be called on any object that inherits from IMarkerInterface, and the implementation would only have to be defined once.

  15. Okay, I see the point now. The “building in memory” idea is an interesting one too. I think I’d still rather have proper support for interface delegation (which is basically what I mean when I use the word “mix-in”) as a full part of the language.

    Jon

Comments are closed.