Having just listened to a recent .Net Rocks! podcast with Anders Hejlsberg (chief architect of the C# language) in a fittingly named show, “Anders Hejlsberg blows our mind!”, I felt it worthwhile to note down some of the views Anders shared with us, and some nice quotes for you to use in your next geek conversation :-P
Recent changes to C# language have introduced more functional and dynamic features to a traditionally imperative and statically typed language.
Language extensions such as LINQ introduced an isolated set of functional features (the introduction of the LINQ query language for example) and through its different flavours (Linq2SQL, Linq2XML and Linq2Objects) allows for a unified way of working with data – something that has been lost since the days of old when concerns such as scalability, transactions, etc. drove a breakaway of data management capabilities into the Relational Database realm, away from the land of general purpose programming languages.
Besides being a data query language, LINQ is also a data transformation language allowing for the transformation of data between objects and XML, or SQL. It also moves the level of abstraction upwards, allowing developers to work on a higher level and say more about the ‘what’ rather than the ‘how’. This elevation of the abstraction level is important because it lends a greater support for a concurrent execution environment – PLINQ for instance allows for parallel execution of LINQ queries on multiple cores.
In the years gone by, the hardware evolution has provided for a quick and easy way to solve our software performance problems, as CPUs’ clock speeds go up they provide an all-around increase in performance to all our software. However, the increase in clock speed has dried up because we have hit the physical limit as CPUs get too hot, and so began the current cycle of multi-core CPUs.
This presents a different challenge for software developers as they can no longer just rely on the hardware to solve performance issues and have to be smart to leverage off the potentials of the new generation of CPUs:
“The free lunch is over, now you really have to learn to cook!”
Whilst concurrent programming is hard, the language is trying to make it easier by introducing PLINQ and the Task Parallel Library (TPL), and Anders foresees future changes which will make it easier to create immutable types which work better in a concurrent environment (see my post on immutable structs here). But bear in mind that not all things can be parallelised and even those that can be parallelise they don’t always guarantee a linear gain in performance.
The problem with the existing thread creation functions in C# is that we have a fairly shallow representation of the OS resources, which are relatively expensive – they don’t consume a lot of physical memory but they consume lots of logical address space. By default, every time you create a thread a MB of logical address space is allocated to the thread, and with only 2–3 GB of available logical space in a 32bit machine you’re only allowed a few thousand threads concurrently.
The TPL provides a way for us to decouple our work from the threads, and enables us to reason about generating logical units of work without having to worry about thread affinity.
On Functional Programming
“Functional programming is wonderful, except when you have to write real apps.”
In a pure functional programming language, there can be no side effects, but in any real-world applications there has to be side-effects somewhere, writing to a log file is a side effect and so is updating a row in the Database.
So the trick is to identify areas in your application which doesn’t require side effects and write islands of functional code, and find ways to marry them to imperative code for their side effects. The great thing about no having any side effects is that you can rule out any consideration about state changes when you call a method, e.g. when you call Math.Round() on a number you know what you’re gonna get and you never stop to think about the consequences of calling it twice because there’re no side effects when you call the method and for the same argument it will always return the same value.
On Dynamic Typing and C# 5
In C# 4, the support for dynamic typing has been added to the language. This has been introduced very much with the challenges developers face from day to day in mind, because we work with non-schematised data structures all the time, e.g. every time you work against a cloud data service.
And finally, briefly touching on what’s to come in C# 5, Anders talked about the theme of C# 5 – meta programming. Some of the work he’s doing now is about opening up the compiler, and providing the compiler as a service. This will make it possible for us to break away from the traditional compiler model of working with source files, and enable us to have interactive prompts and REPL like the F# Interactive window that is available for F#. This also opens the door for meta programming capability, programs that writes itself, a feature that has driven the success of Ruby and Ruby on Rails.