Bio A former computer science professor from Aarhus University, Mads joined the C# team at Microsoft as a Senior Program Manager. As a Microsoft Program Manager, Mads is responsible for the LINQ additions to C# shaping its future and the future of programming languages at Microsoft. Mads is a frequent speaker at many technical conferences including JAOO and has been highlighted on Channel 9.
Yes. I am local, I'm from Denmark and lived here until 2 years ago. I used to be a university professor, doing programming language design, working with Java. For the past 2 years I've been working for Microsoft, designing and evolving the C# language.
You'd think so. There are a lot of new features and all but one of them are actually extremely general purpose. We put in a single feature that is basically creating expressions themselves and looks very much like a SQL-like language. That's all about create, but all the other facilities we put into LINQ we were very careful to make sure that they were not too specific. The intent is to provide general purpose language features that you'd find in other languages and would be useful in a lot of contexts. In particular LINQ is very expression oriented or declarative so we took a lot of inspiration or you could also say that we went and stole a lot of stuff from the world of functional programming languages which have this declarative expression oriented style. And so, some people claim that C# is becoming more and more of a functional programming language. There are plenty and plenty of ways that you can use that in all sorts of programming. It provides a style of programming that does less mutation and does more things in a declarative style, it makes it a lot easier.
Give people a useful tool and they can misuse it. There is always a danger of adding too much complexity to a language when you add new features. The language becomes bigger and given the compatibility constraints, we can't take that other stuff away. So we're always very careful about how much we add to the language. Now with some of these new features people have expressed concerns, for instance we have extension methods that allow you to write methods that look as if they were defined in another class when you call them. People say: "Isn't that sort of security concern?" or can be misused in all sorts of ways. I don't think there is a really big problem here, it is very much whenever there is an extension method you choose whether you want to have it or not. Sure, you can have people go all over the place and use extension methods for everything. We'll, as always, come out with a set of guidelines for when it's proper or not too proper to use this stuff. Having extension methods all over the place is probably going confuse everyone else who reads your code. As usual, we just have to give guidance.
My single favorite worst use of extension methods. I warn you don't do this at home, it is the isnull() method. Imagine running an extension method that allows you to go up to an object reference, a variable, and say v.isnull() and if the content of the variable is null it will not throw a null reference exception, but instead it will return the value true. That's the kind of thing that just confuses the heck out of people, because they change the expected behavior. The best use is when you add new types or new concepts to an application area that interact with all types that are already defined in somebody else's code or libraries and there is a certain pattern of interaction between the old and the new types that you want to describe. It's often possible to do that in a more symmetric way if you can add or seemingly add functionality to the old types to interact with the new ones as well as the other way. So, that's one of the good uses.
C# 2.0 already had some type inference for calling generic methods. We now also add the facility of type inference for local variables, so instead of putting a type on a local variable, you can just set the keyword var and that means:"Go and look at the thing you're initializing with, figure out its type and stick that type as the type of the local variable. It's a seemingly little thing, but it allows you to emit a lot of redundancy when you talk about huge, big generic types that have a lot of type arguments. It also tends to, in a strange sort of way, it often tends to make your code more fluent in a way, when it's kind of obvious what the right hand side is you don't want to even talk about the types, you just have them in the back of your had. I think it's a feature that again it can be abused, people will tend to use it everywhere maybe, but on the other hand I am not so conservative about when you should use var instead of putting the type, especially in these days when people tend to use an IDE for most of their work and if you go to Visual Studio and do this you can always hover over the variable and get its type and if you really want it, it doesn't necessarily have to be manifest in the code.
In a sense it is only about querying data, but data in the most general sense of the word, like if you think about all the objects that you have in your program as also being data then yes, it's only about asking questions of data, but since all your objects are really data, what I find is that when you program with LINQ for a little while, these little queries tend to creep into all sorts of little places where you would have done things in a much more imperative way, in a more heavy way, again describing too much of the how to get information and not just what you want to know. So in all these little places that are not really about accessing a database or processing an XML document or something like that, you also get LINQ popping up all over the place. That I think is testimony to the success of the feature. It really creeps into your code in the tiniest ways and helps your code become more readable. Even when you wouldn't have ever thought about it as querying, just as obtaining some information, doing a bit of analysis in the objects and a little computation.
As a whole in .NET, we are thinking a lot about parallelism; of course this has become urgent with the advent of multi-cores all over the place. We really now have to figure out what is the right thing to do with concurrency. You see so many competing answers to how concurrency and synchronization should be handled that we're basically looking into them all. We're trying to figure out which ones are good and which ones aren't and to what extend they live together. That is a slightly longer term project. In the short term we are already trying to do things to make parallel programming better for some specific scenarios. One thing that I am particularly proud of that is in incubation going on right now, and we should get some public stuff out pretty soon, we are calling "parallel effects". It is a set of useful methods and classes for doing parallel for() loops like you want to do a for() loop, except that all the iterations happen at once, for doing futures which are values that you can pass around while you are still computing and perhaps most importantly a parallel version of the in-memory LINQ queries that will actually take a query over a chunk of data and parallelize it across multiple processes and do bits of the query in parallel on each processor and they merge the result at the end, which is a really easy way of doing parallel programming from the user's perspective because you are just writing the same old LINQ queries. They just run many times faster. So we are taking the specific scenarios where you have data parallelism, it's a slam-dunk optimization, as you can use all the processes just utilizing that. For the more general purpose hard problems, it will be a little longer, I think, before we have them nailed.
I think that we definitely need something new to happen. It's clear that we have a long way to go before we can handle this problem. I am unclear about weather we really need to throw out all the old stuff and start over. That tends to happen only very rarely, so I would be happy if we can find a way. I would love to use the ideas of isolation and statelessness that you have in a language like Erlang and apply them in current programming languages or maybe extend them in that direction. To that extent, that's also a whole problem that remains to be seen. I certainly hope that we do not have to throw out all the wisdom of object oriented programming and all the lazy code and all that. But if it really is a paradigm change, the first thing is that people who are in it don't know what is really happening. So I wouldn't be able to tell you. And the second is that if it happens it happens and we'll have to go with it and that's really what it takes. The whole programming world is going down the drain. We'll just have to go there. I don't think we are quite there yet, we are exploring a more evolutionary approach.
We're diverging in some ways and we're evolving in parallel in other ways. LINQ, has been introduced in parallel on both sides and that has been the major set of features for both. I actually think that's an example of evolving in parallel. We do both. We‘re quite conscious about having slightly different user constituencies and it's difficult to always characterize them in a crisp way. But it's just that sometimes when you look at a feature we think that our users will probably not have that one and VB thinks that their use is on the whole will be happier with it. It's because we have different users they come out differently sometimes. We tend to try to not introduce unnecessary difference between the languages. Maybe we don't always succeed or haven't always succeeded in the past, but we try at least. Whenever we are doing the same thing we are trying to do it exactly the same way, like having the same semantics and that kind of stuff. This, because there's no reason to confuse people unnecessarily and we do coordinate a lot. Their features are going one way in their language and not in the other and that's just catering to the different kinds of applications that are written and the different users that we have. It will keep going on like that, diverging, going in parallel for a while, that's just the story of .NET and VB.
That is very good question because right now we are rolling out this whole new approach to dealing with dynamic languages. They have a common platform that we call the DLR, (The Dynamic Language Runtime), and it's intended to be a common execution platform for new dynamic languages or newcomers to .NET. Python, Ruby and maybe other languages that people will make and they are welcome to the platform, certainly, and also to provide interfaces to COM, for instance, that are more dynamic than what we have today. So the question becomes, now that we have all these languages and they're well integrated in the sense that they can consume existing DOTNET APIs that strongly typed and statically typed. That introduces sort of a symmetry because existing languages are not very good at consuming dynamic stuff. They cannot do dynamic method calls, a virtual dispatch that the compiler doesn't know that their method is there. In order to introduce symmetry, we might look into and I think we're going to look into having that kind of feature in C#. Saying explicitly: "I want to do a dynamic method call. I know dear compiler that you don't know that such a method exists, but I believe it does so please let me call it anyway." Today you have to use reflection to do that and I think it will just make that easier, it's useful for a lot of things, including consuming, code written in the new dynamic languages.
In a major way, to be honest, I think not every single feature that we added, but maybe 90% of them are to some degree inspired by features in functional programming languages, including actually the query expressions themselves are an example of what the programming languages call comprehensions. Which is a thing that's an incomprehensible word so we used another one, but it's very inspired by that and there is a reason for that. It has this nice declarative feel to it. You don't have to say how. You just say why. It all just plays really nicely together in this functional way. I think in the future, talking about concurrency, not mutating stuff so much and being less imperative becomes a really good thing when you talk about concurrency. Because the stuff that is hard to coordinate is when you change the shared state or whenever you modify the state of the program. And if you can modify the state of the program less, you have less to worry about. Adopting a more functional style and perhaps supporting that with even more features from functional programming languages becomes a real benefit there as we move towards handling concurrency better. I think it's also an investment for the future.
That would be a great idea, I think we should do that. We actually have, inside Microsoft, some functional programming languages already on .NET. In particular, in Microsoft Research there is an increasingly popular language called F#. It's currently not a product. It's a research project. F# is a derivative of the functional programming language ML and it runs nicely on .NET. One of the things it does is to integrate well with .NET and this sort of object oriented fabric of .NET by having really good object oriented features. Much better than the ones who tend to have another functional programming language. Maybe we have this big unification and it's looking at it from the other side and the languages might end up meeting someone in the middle in terms of their functionality. They have very different styles. I think even if these two camps of languages are coming together and moving toward each other, just because of the different styles, they will keep appealing to different audiences. I think it will definitely add richness if we get to the point where we can take a functional programming language such as F#, it's a really strong suggestion in that area and put it out is a real support language sometimes and I'd love for that to happen someday.
Only if Joe Armstrong gets it the way he thinks it will be. If the paradigm shifts, then supposedly we will all be going to be supporting functional languages after that. But until then no, I think they serve purposes that are different styles of programming that you can use for different kinds of applications. They can co-inhabit the world quite nicely.
I never read computer books. That is boring.