Computerworld is undertaking a series of investigations into the most widely-used programming languages. Previously we have spoken to Alfred v. Aho of AWK fame, S. Tucker Taft on the Ada 1995 and 2005 revisions, Microsoft about its server-side script engine ASP, Chet Ramey about his experiences maintaining Bash, Bjarne Stroustrup of C++ fame, and Charles H. Moore about the design and development of Forth.
MORE ON CIO.COM
In this interview Microsoft's leader of C# development, Anders Hejlsberg, took some time to tell Computerworld about the development of C#, his thoughts on future programming trends, and his experiences putting out fires. Hejlsberg is also responsible for writing the Turbo Pascal system, and was the lead architect on the team that developed Delphi.
(Please note that due to popular demand we are no longer following alphabetical order for this series. If you wish to submit any suggestions for programming languages or language authors you would like to see covered, please email firstname.lastname@example.org.)
What were the fundamental flaws in other languages that you believe drove the development of Common Language Runtime (CLR), and in turn, C#?
I wouldnt say that our primary motivation for CLR was fundamental flaws in other languages. But we certainly had some key goals in mind. Primarily, we wanted to build a unified and modern development platform for multiple programming languages and application models.
To put this aim in context, we need to look back to the inception of .NET, which was in the late nineties or early 2000s. At that time, Microsofts primary developer offerings were fairly fragmented. For native code we had C++ with MFC, and ATL and so forth. And then for rapid application development we had Visual Basic, and for web development we had IIS and ASP.
Each language was its own little silo with different solutions to all of the different programming problems. You couldn't transfer your skills and your application model implicitly became your choice of programming language. We really wanted to unify these separate entities to better leverage our efforts.
We also wanted to introduce modern concepts, such as object orientation, type safety, garbage collection and structured exception handling directly into the platform. At the time, the underlying infrastructure we were running on was COM, which is a very low level programming model that requires you to deal with the registry and reference counting and HRESULTs and all that stuff.
These factors were, at the time, the motivators for .NET. There was also a competitive angle with Sun and Java etc.
Now, to move on to C#, in a nutshell our aim was to create a first class modern language on this platform that would appeal to the curly braces crowd: the C++ programmers of the world at the time, and competitively, the Java programmers.
There were several elements that we considered key design goals, like support for the next level up from object oriented programming, to component based programming where properties and metadata attributes were all first class in the language. Also, a unified and extensible type system, which sort of gets into value types and boxing etc. Versioning was a big thing; making sure we designed the language so that it would version well, so that whenever we added new features to the language we would not break code in older applications. These were all values that were important to us.
Of course, at the end of the day, productivity has always been a driver for me in all of the projects I've worked on. It's about making programmers more productive.
Why was the language originally named Cool, and what promoted the change to C#?
The code name was Cool, which stood for 'C like Object Oriented Language'. We kind of liked that name: all of our files were called .cool and that was kind of cool! We looked seriously at keeping the name for the final product but it was just not feasible from a trademark perspective, as there were way too many cool things out there.
So the naming committee had to get to work and we sort of liked the notion of having an inherent reference to C in there, and a little word play on C++, as you can sort of view the sharp sign as four pluses, so it's C++++. And the musical aspect was interesting too. So C# it was, and I've actually been really happy with that name. It's served us well.
How has your experience designing Visual J++, Borland Delphi and Turbo Pascal impacted on C#?
If you go back to the Turbo Pascal days, the really new element created by Turbo Pascal was that it was the first product ever to commercialize the integrated development environment, in a broad sense—the rapid turnaround cycle between compile, edit or edit, compile, debug. Any development tool today looks that same way, and that of course has always been a key thing.
[I also learnt to] design the language to be well-toolable. This does impact the language in subtle ways—you've got to make sure the syntax works well for having a background compiler, and statement completion. There are actually some languages, such as SQL, where it's very hard to do meaningful statement completion as things sort of come in the wrong order. When you write your SELECT clause, you can't tell what people are selecting from, or what they might select until after writing the FROM clause. There are things like that to keep in mind.
Each of the products I've worked on, I'd say, have taught me valuable lessons about what works and what doesn't, and of course you end up applying that knowledge to subsequent products you work on. For example, Delphi was the first product I worked on to natively support properties, and then that got carried over to C# for example. We added a similar feature there.
Have you encountered any major problems in the development of C#? Any catastrophes?
No, I wouldn't say that there have been any catastrophes! But life is nothing but little missteps and corrections along the way, so there are always little fires you're putting out, but I wouldn't say we ever had total meltdowns. It's been a lot of fun to work on and it's been over 10 years now.
Can you give me an example of a little fire that you've had to put out?
Every project is about not what you put in, but what you don't have time to put in! So it's always about what we're going to cut& so every project is like that. It's so hard to single out anything in particular as we're always putting out fires. New people leave the team and new people come in, it's like every day you come to work and there's something new to be dealt with.
Would you do anything differently in developing C# if you had the chance?
There are several things. First of all, when we shipped C# 1.0 we did not have generics in the language—that came in C# 2.0, and the minute we shipped generics we were able to put a lot of old code to bed as it was superfluous and not as strongly typed as generics. So a bunch of stuff got deprecated right out of the box in C#2.0. We knew generics were coming but it was one of those hard decisions: do you hold the platform longer or do you ship now and work on this and then ship it a couple of years later? I would have loved to have generics from the beginning as it would have left us with less obsolete stuff in the framework today.
With language design or with platform design 1.0 is always a unique opportunity to put down your core values, your core designs, and then with every version thereafter it's much harder to fundamentally change the nature of the beast. And so, the things that you typically end up regretting later are the fundamentals that you didn't quite get right. Because those you can't change - you can always ship new libraries etc, but you can't change the fundamental gestalt of the platform.
For example, in the type system we do not have separation between value and reference types and nullability of types. This may sound a little wonky or a little technical, but in C# reference types can be null, such as strings, but value types cannot be null. It sure would be nice to have had non-nullable reference types, so you could declare that 'this string can never be null, and I want you compiler to check that I can never hit a null pointer here'.
50% of the bugs that people run into today, coding with C# in our platform, and the same is true of Java for that matter, are probably null reference exceptions. If we had had a stronger type system that would allow you to say that 'this parameter may never be null, and you compiler please check that at every call, by doing static analysis of the code'. Then we could have stamped out classes of bugs.
But peppering that on after the fact once you've built a whole platform where this isn't built in& it's very hard to pepper on afterwards. Because if you start strengthening your APIs and saying that you can't pass null here or null here or null here, then all of a sudden you're starting to break a bunch of code. It may not be possible for the compiler to track it all properly.
Anyway, those are just things that are tough later. You sort of end up going, well ok, if we ever get another chance in umpteen years to build a new platform, we'll definitely get this one right. Of course then we'll go and make other mistakes! But we won't make that one.
Why do you think C is such a popular language base, with many languages built on it such as C++ and C#?
I think you have to take the historic view there first. If you go back to C itself, C was a very, very appropriate language for its time. It was really the language that lifted operating system builders out of assembly code and gave them higher level abstractions such as data types and so forth, yet was sufficiently close to the machine so that you could write efficient code. It was also very succinct: it was a very terse language, you can write very compact code which is something that programmers very much prefer. You compare a C program to a COBOL program and I can tell you where you're going to see more characters.
So C was just an incredibly appropriate language for its time, and C++ was an incredibly appropriate evolution of C. Once you have huge language use, it is much easier to evolve and bring an existing base with you than it is to go create something brand new. If you look at the mechanics of new languages, when you design a new language you can either decide to evolve an existing language or start from scratch.
Evolving an existing language means you have an instantaneous big user base, and everything you add to the language is just gravy... there's really no draw back as all of the old code still works. Start with a brand new language and you essentially start with minus 1,000 points. And now, you've got to win back your 1,000 points before we're even talking. Lots of languages never get to more than minus 500. Yeah, they add value but they didn't add enough value over what was there before. So C++ I think is a fantastic example of a very appropriate evolution of an existing language. It came right at the dawn of object oriented programming and pioneered that right into the core programming community, in a great way.
Of course by the time we started looking at C# as a new language, there was a huge, huge number of programmers out there that were very accustomed to programming with curly braces, like the C guys, C++ guys, Java guys etc etc. And so for us that was a very natural starting point: to make a language that would appeal to C++ programmers and to Java programmers. And that really meant build a language in the C heritage. And I think that has served us very, very well.
What do you think of the upcoming language F#, which is touted as a fusion of a functional language and C#?
I'm very enthusiastic about F# and the work that Don Syme from Microsoft Research in Cambridge is doing on this language. I wouldn't say it's a fusion of ML and C#. I mean, certainly its roots come from the ML base of functional programming languages, and it is closely related to Caml. I view it as a fusion of Caml and .NET, and a great impact of tooling experience.
Do you think that it's ever going to become a large competitor to C#?
I think they are both great and very complimentary. A competitor, yes, in the sense that VB is a competitor. But do you think of them as competitors? Or do you think of them as languages on a unified platform? I mean, I don't personally: to me, the important thing is what's built on top of .NET. Every language borrows from other languages, but that's how we make progress in the industry and I'm interested in progress.
What do you think of functional programming in general?