Sponsored By Aspose - File Format APIs for .NET

Aspose are the market leader of .NET APIs for file business formats – natively work with DOCX, XLSX, PPT, PDF, MSG, MPP, images formats and many more!

What Is the Future of C# Anyways?

It was often asked during some of my presentations on F# and Functional C# about the future direction of C# and where I think it’s going.  Last night I was pinged about this with my F# talk at the Philly ALT.NET meeting.  The question was asked, why bother learning F#, when eventually I’ll get these things for free once they steal it and bring it to C#.  Being the language geek that I am, I’m pretty interested in this question as well.  Right now, the language itself keeps evolving at a rather quick pace as compared to C++ and Java.  And we have many developers that are struggling to keep up with the evolution of the language to a more functional style with LINQ, lambda expressions, lazy evaluation, etc.  There are plenty of places to go with the language and a few questions to ask along the way.

An Interview With Anders Hejlsberg

Recently on Software Engineering Radio, Anders Hejlsberg was interviewed about the past, present and future of C# on Episode 97.  Of course there are interesting aspects of the history of his involvement with languages such as Tubro Pascal and Delphi and some great commentary on Visual Basic and dynamic languages as well.  But, the real core of the discussion was focused around what problems are the ones we need to solve next?  And how will C# handle some of these features?  Will they be language constructs or built-in to the framework itself? 

Let’s go through some of the issues discussed.

Concurrency Programming

Concurrency programming is hard.  Let’s not mince words about it.  Once we start getting into multiple processors and multiple cores, this becomes even more of an issue.  Are we using the machine effectively?  It’s important because with the standard locks/mutexes it’s literally impossible to have shared memory parallelism with more than two processors without at some point being blocking and serial. 

The way things are currently designed in the frameworks and the languages themselves are not designed for concurrency to make it easy.  The Erlang guys of course would disagree since they started with that idea from the very start.  Since things are sandboxed to a particular thread, they are free to mutate state to their heart’s content, and then when they need to talk to another process, they pick up the data and completely copy it over, so there is a penalty for doing so.  Joe Armstrong, the creator of Erlang, covered a lot of these things in his Erlang book “Programming Erlang: Software for a Concurrent World “.

Mutable State

Part of the issue concerning concurrency is the idea of mutable state.  As far back as I remember, we were always taught in CS classes that you can feel free to mutate state as need be.  But, that only really works when you’ve got a nicely serial application where A calls B calls C calls D and all on the same thread.  But, that’s a fairly limiting thing idea as we start to scale out to multiple threads, machines and so on.  Instead, we need to focus on the mutability and control it in a meaningful way through not only the use of our language constructs, but our design patterns as well.

In the C# world, we have the ability to create opt-in immutability through the use of the readonly keyword.   This is really helpful to decide those fields that we don’t really need to or want to modify.  This also helps the JIT better determine the use of our particular variable.  I’m not sure about performance gains, but that’s not really the point of it all, anyways.  Take the canonical example of the 2D point such as this:

public class Point2D
{
    private readonly double x;
    private readonly double y;

    public Point2D() { }

    public Point2D(double x, double y)
    {
        this.x = x;
        this.y = y;
    }

    public double X { get { return x; } }

    public double Y { get { return y; } }

    public Point2D Add(Size2D size)
    {
        return new Point2D(x + size.Height, y + size.Width);
    }
}

We’ve created this class as to not allow for mutable state, instead returning a new object that you are free to work with.  This of course is a positive thing.  But, can we go further in a language than just this?  I think so, and I think Anders does too.  Spec# and design by contract can take this just a bit further in this regard.  What if I can state that my object, as it is, is immutable?  That would certainly help the compiler to optimize.  Take for example doing Value Objects in the Domain Driven Design world.  How would something like that look?  Well, let’s follow the Spec# example and mark my class as being immutable, meaning that once I initialize it, I cannot change it for any reason:

[Immutable]
public class Point2D
{
   // Class implementation the same
}

This helps make it more transparent to the caller and the callee that what you have cannot be changed.  This enforces the behaviors for my member variables in a pretty interesting way.  Let’s take a look at the actual C# generated in Spec# for the above code.  I’ll only paste the relevant information about what it did to the properties.  I’ll only look at the X, but the identical happened for the Y as well.

public double X
{
    [Witness(false, 0, “”, “0”, “”), Witness(false, 0, “”, “1”, “”), Witness(false, 0, “”, “this@ClassLibrary1.Point2D::x”, “”, Filename=@”D:\Work\SpecSharpSamples\SpecSharpSamples\Class1.ssc”, StartLine=20, StartColumn=0x21, EndLine=20, EndColumn=0x22, SourceText=”x”), Ensures(“::==(double,double){${double,\”return value\”},this@ClassLibrary1.Point2D::x}”, Filename=@”D:\Work\SpecSharpSamples\SpecSharpSamples\Class1.ssc”, StartLine=20, StartColumn=20, EndLine=20, EndColumn=0x17, SourceText=”get”)]
    get
    {
        double return value = this.x;
        try
        {
            if (return value != this.x)
            {
                throw new EnsuresException(“Postcondition ‘get’ violated from method ‘ClassLibrary1.Point2D.get_X'”);
            }
        }
        catch (ContractMarkerException)
        {
            throw;
        }
        double SS$Display Return Local = return value;
        return return value;
    }
}

What I like about F# and functional programming is the opt-out mutability, which means by default, my classes, lists, structures and so on are immutable by default.  So, this makes you think long and hard about any particular mutability you want to introduce into your program.  It’s not to say that there can be no mutability in your application, but on the other hand, you need to think about it, and isolate it in a meaningful manner.  Haskell takes a more hardline stance on the issue, and mutability can only occur in monadic expressions.  If you’re not aware of what those are, check out F# workflows which are perfectly analogous.  But by default, we get code that looks like this and is immutable:

type Point2D = class
  val x : double
  val y : double
 
  new() = { x = 0.0; y = 0.0 }
 
  new(x, y) =
    {
      x = x
      y = y
    }

  member this.X
    with get() = this.x
   
  member this.Y
    with get() = this.y
end

So, as you can see, I’m not having to express the immutability, only the mutability if I so choose.  Very important differentiator.

Method Purity

Method purity is another important topic as we talk about concurrent programming and such.  What I mean by this is that I’m not going to modify the incoming parameters or cause some side effects, and instead I will produce a new object instead.  This has lasting effects if I’m going to be doing things on other threads.  Eric Evans talked about this topic briefly in his Domain Driven Design book on Supple Design.  The idea is to have side effect free functions as much as you can, and carefully control where you mutate state through intention revealing interfaces and so on.

But, how do you communicate this?  Well, Command-Query Separation gets us part of the way there.  That’s the idea of having the mutation and side effects in your command functions where you return nothing, and then queries which return data but do not modify state.  Spec# can enforce this behavior as well.  To be able to mark our particular functions as being pure is quite helpful in communicating whether I can expect a change in state.  Therefore I know whether I have to manage the mutation in some special way.  To communicate something like that in Spec#, all I have to do is something like this:

[Pure]
public Point2D Add(Size2D size)
    requires size != null;
{
    return new Point2D(x + size.Height, y + size.Width);
}

This becomes part of the method contract and some good documentation as well for your system.

Asynchronous Communication and Messaging

Another piece of interest is messaging and process isolation.  The Erlang guys figured out a while ago, that you can have mutation as well as mass concurrency, fail safety and so on with process isolation.   Two ideas come to mind from other .NET languages.  An important distinction must be made between concurrency memory models between shared-memory and message passing concurrency.  Messaging and asynchronous communication are key foundations for concurrent programming. 

In F#, there is support for the mailbox processing messaging.  This is already popular in Erlang, hence probably where the idea came from.  The idea is that a mailbox is a message queue that you can listen to for a message that is relevant to the agent you’ve defined.  This is implemented in the MailboxProcessor class in the Microsoft.FSharp.Control.Mailboxes namespace.  Doing a simple receive is pretty simple as shown here:

#light

#nowarn “57”

open Microsoft.FSharp.Control.CommonExtensions
open Microsoft.FSharp.Control.Mailboxes

let incrementor =
  new MailboxProcessor<int>(fun inbox ->
    let rec loopMessage(n) =
      async {
              do printfn “n = %d” n
              let! message = inbox.Receive()
              return! loopMessage(n + message)
            }
    loopMessage(0))

Robert Pickering has more information about the Erlang style message passing here

Now, let’s come back just a second.  Erlang also introduces another concept that Sing# and the Singularity OS took up.  It’s a concept called the Software Isolated Process (SIP).  The idea is to isolate your processes in a little sandbox.  Therefore if you load up a bad driver or something like that, the process can die and then spin up another process without having killed the entire system.  That’s a really key part of Singularity and quite frankly one of the most intriguing.  Galen Hunt, the main researcher behind this talked about this on Software Engineering Radio Episode 88.  He also talks about it more here on Channel9 and it’s well worth looking at.  You can also download the source on CodePlex and check it out.

Dynamic C#?

As you can probably note, Anders is pretty much a static typing fan and I’d have to say that I’m also firmly in that camp as well.  But, there are elements that are intriguing such as metaprogramming and creating DSLs which are pretty weak in C# as of now.  Sure, people are trying to bend C# in all sorts of interesting ways, but it’s not a natural fit as the language stands now.  So, I think there can be some improvements here in some areas.

Metaprogramming

Metaprogramming is another area that was mentioned as a particularly interesting aspect.  As of right now, it’s not an easy fit to do this with C#.  But once again, F# has many of these features built-in to do such things as quotations to do some metaprogramming because that’s what it was created to do, a language built to create other languages.  Tomas Petricek is by far one of the authorities on the subject as he has leveraged it in interesting ways to create AJAX applications.  You can read about his introduction to metaprogramming here and his AJAX toolkit hereDon Syme has also written a paper about leveraging Meta-programming with F# which you can find here.  But I guess I have to ask the question, does C# need this or shouldn’t we just use F# for what it’s really good at and not shoehorn yet another piece onto the language?  Or the same could be said of Ruby and its power with metaprogramming as well, why not use the best language for the job?

Dynamic Dispatch

The idea of dynamic dispatch is an interesting idea as well.  This is the idea that you can invoke a method on an object that doesn’t exist, and instead, the system figures out where to send it.  In Ruby, we have the method_missing concept which allows us to define that behavior when that method that is being invoked is not found.  Anders thought it was an intriguing idea and it was something to look at.  This might help in the creation of DSLs as well when you can define that behavior even though that method may not exist at all.

In the Language or the Framework?

Another good question though is do these features belong in the language itself or the in the framework?  The argument here is that if you somehow put a lot of constraints on the language syntax, then you might prematurely age the language and as a result, decline in usage.  Instead, the idea is to focus on the libraries to make these things available.  For example, the MailboxProcessor functionality being brought to all languages might not be a bad idea.  Those sorts of concepts around process isolation would be more of a framework concept than a language concept.  But, it’s an interesting debate as to what belongs where.  Because at the end of the day, you do need some language differentiation when you use C#, F#, Ruby, Python, C++, etc or else what’s the point of having all of them?  To that point I’ve been dismayed that VB.NET and C# have mirrored themselves pretty well and tried to make themselves equal and I wish they would just stop.  Let VB find a niche and let C# find its niche. 

Conclusion

Well, I hope this little discussion got you thinking as well about the future of C# and the future of the .NET framework as well.  What does C# need in order to better express the problems we are trying to solve?  And is it language specific or does it belong in the framework?  Shouldn’t we just use the best language for the job instead of everything by default being in C#?  Good questions to answer, so now discuss…

This entry was posted in C#, F#, Spec#. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • Test

    I am enjoying this discussion. I think all programming language are important.
    keylogger

  • http://podwysocki.codebetter.com Matthew Podwysocki

    @Jared

    No, Spec# is also a compile time theorem prover, hence why you will find green squigglies to show violations of your contracts. Boogie is a compile time theorem prover which verifies your code at compile time. Sure, it compiles down to IL which does the checks also at run time, but the compile time features are the powerful features. I suggest you download Spec# and read the papers written by Rustan on the Spec# site.

    Matt

  • http://blogs.msdn.com/jaredpar Jared Parsons

    @Matt,

    I think you’re misunderstanding me. I believe the correct approach to immutability is to decarorate class with an attribute as you’ve shown.

    What I don’t understand is why a runtime check should be done vs. a compile time check. My limited understanding of Spec# has it pegged as a runitme tool. Compile time checks for immutability are possible and once they’re verified there is no reason to have a runtime check.

    Also I’m not arguing against DBC. I’m argueing for doing as much contract checking at compile time vs. runtime.

  • http://podwysock.codebetter.com Matthew.Podwysocki

    @Bryan

    Thanks! There is much more to cover with this topic, so we’ll see where it leads.

    Matt

  • http://podwysock.codebetter.com Matthew Podwysocki

    @Julien

    Yes, I did similar checks, but quite frankly it doesn’t matter as much, because the concepts about readonly to me are stronger for enforcing whether you want your member variables to be immutable. Maybe later the JIT could optimize but I don’t think it has right now.

    Matt

  • http://podwysock.codebetter.com Matthew Podwysocki

    @Jared

    I think you’re missing the power to specify these things in code without having to place such items in the inside of your methods, instead to make it explicitly part of the method and class contract. That’s where the power lies. To make it explicit to both the caller and callee without having to resort to the documentation, and in fact the methods and classes become self documenting.

    Also, when you mention FxCop, we can do one better with Boogie, the static verifier used by Spec# to catch these contract failures at compilation time instead of having to run any external tool. To get the green squigglies to indicate where you have contract failures is important. As soon as you understand Design by Contract, it will make a bit more sense.

    Matt

  • http://podwysock.codebetter.com Matthew Podwysocki

    @Keith Hill

    Agreed about macros. It’s an awfully useful feature in Lisp and I wish we had similar mechanisms in C#. Also, the ability to have the Before and After methods from Lisp as well would be pretty helpful.

    Matt

  • http://podwysock.codebetter.com Matthew Podwysocki

    @jdn

    I don’t think you understand the context of immutability. The ideas behind command-query separation are what we’re talking about in regards to managing your mutations, where we only mutate during commands, and not queries.

    I didn’t say anything about no immutability, because that’s just silly, and even Haskell has it through monadic computations. Instead, being aware of it and designing where and how it is done is key. Meaning that if you have shared state/memory between threads, it needs to be managed. Instead, if we have objects that are initialized and then immutable, we don’t have to worry as much.

    In Domain Driven Design, we strive for immutable value objects, set once and forget and if you need a new one, you create one. We also focus on mutating our entities through intention revealing interfaces. And we also focus on side effect free functions. Once you understand that, then you’ll understand immutability.

    Matt

  • http://www.thedotnetfrog.com Julien

    If you’re interested, there’s no real performance gain with the readonly keyword (there might be a gain in some case but it’s quite dependant on the hardware): http://www.thedotnetfrog.com/2008/04/22/performance-impact-of-the-readonly-keyword/

  • http://blogs.msdn.com/jaredpar Jared Parsons

    I don’t understand the bit about Spec# and immutability. This is more likely due to my ignorance of the inner workings of Spec# than anything else. But from the code you produced it looks like Spec# is doing a runtime check to guarantee immutability. This seems like a waste of runtime time because the immuability or non-immutability of a class can be verified at compile time.

    Don’t mistake my question for a bashing of Spec#. It just seems that immutability is better left to a static analysis tool such as FxCop or the compiler itself. Perhaps even the CLR.

  • http://keithhill.spaces.live.com Keith Hill

    +1 on metaprogramming in C#. C/C++ text substitution macros are a double edged sword and I’m glad C# chose not to implement them. However I do miss them at times. I would like some sort of compile-time checked/safe macro language within C#.

    Take for instance, the automatic properties impl in C# 3.0. That is nice, but if I’m implementing the INotifyPropertyChanged interface on a type with dozens of poperties that is an awful lot of pure boiler plate code that automatic properties doesn’t help with in any way. I wish I could define a “macro” (more like a Lisp defmacro) that would let me define the boiler plate code and give it a name like NotifyProperty e.g.:

    public NotifyProperty string Name {get; set; }

    I could imagine creating a similar DependencyProperty macro for WPF custom controls.

  • http://Bryan.ReynoldsLive.com Bryan Reynolds

    Great article! Thanks.

  • http://www.blogcoward.com jdn

    To ask a potentially dumb question about immutability:

    Suppose I have a standard shopping cart + checkout process in an application. Everytime you make a change to any of the things that apply here (Cart Items, Billing Address, etc. etc. etc.), instead of modifying an existing object, you would create a new one and replace the existing one?

    And is immutability important for applications like this?

    To use an analogy, if you really want to make a computer safe from network attacks, disconnect it from the network. But, you lose functionality.

    Similarly, I gather that one of the goals of immutability is to prevent side effects and help prevent the introduction of changes you didn’t intend. But of course, if everything was completely immutable, your code couldn’t actually do anything.