Transcript 97: Interview Anders Hejlsberg

Host(s)

Markus

Guest(s)

Recording venue


In this episode we have the pleasure of talking to Anders Hejlsberg, Chief Language Strategist at Microsoft. We started by discussing his more distant past, namely, his involvement with Turbo Pascal and Borland's Delphi. We then looked at the influences Delphi had on C# and how C# evolved from Delphi. In the next section we discussed a couple of general language design issues, among them components and checked vs. unchecked exceptions. Next, we discussed interesting issues about languages of the future, static vs. dynamic typing, functional programming, meta programming as well as the importance of good support for concurrency. We concluded the discussion by looking at the interplay between languages and IDEs.

Transcripts are brought to you by itemis

Transcript

Okay, welcome listeners to another episode of Software Engineer Radio, this is another one recorded at Microsoft in Redmond. This time we're talking to Anders Hejlsberg. Welcome Anders!

Thank you,

And we're going to start with some historic stuff. Anders has been involved with Pascal, a while ago. So how did you get into Pascal back then?

It was actually in high school, back in the later '70s, mid-late '70s our high school had, what was then called a mini-computer. And on that mini computer we could program in ALGOL. That was the first programming language I was taught, was ALGOL. And then when I got out of high school and into the technical University, I met up with some buddies there, and we started a company. A small company to sell kit computers and make software for kit computers. And I wrote assemblers and disassemblers and all of this kind of stuff that you would write for those. And then, wanted to write a more of a full language compiler, and I wanted to write an ALGOL compiler, because that was what I knew. But then my friend who's going, "You know there's this new thing called Pascal, you should take a look at it." So I did, and it was actually simpler to implement than ALGOL. So that's the way it went. That was actually; the first Pascal compiler I wrote was a little, early, early precursor of Turbo Pascal and it was all written in ZAD assembler and it was 12K, including the compiler runtime and an on screen editor for this kit computer called the NASCOM which was a British kit computer. And you could yank out the Microsoft ROM Basic and then stick in our little Pascal compiler. When you turn power on you were sitting in an editor, and you could type code.

Pascal was actually the first language - well, I started with the Basic on the Amstrad CPC and then at school we had Pascal, I think it was Turbo Pascal 3 thing on Zenith computers. They are very old stuff, and I remember the time when I couldn't imagine, how you could program without line numbers. I didn't know how that would work.

What are you going to go to?

Yeah, exactly. Anyway, so what's the state of Pascal today. Is it still used somewhere or is it --?

It's still, Turbo Pascal is still or it's successor Delphi is still I think used in education in, I forget where -- but I saw a write-up of it a couple of years ago, and certainly then it still was. Although I would say, it's on the decline for sure. But I mean Pascal, evolved over many years and sprouted object orientation and then sort of became a fairly full-fledged language. It never really made the jump into the VM world and byte codes. Well, that's actually not entirely true but UCSD Pascal was really in essence the grandfather of all the byte code systems. Because it had p-code and ran p-code. So if you had like the Apple II had a great implementation of UCSD Pascal and the p-code systems.

I didn't know that. So it is also not typically sided as one of those precursors to the Java VM. People typically talk about Self and Smalltalk --

No, it is probably because it goes back too far. But it was certainly for me, a great inspiration in Turbo Pascal.

So, you already mentioned Delphi, I used it quite a bit -- wrote a couple of hospital data management system with it. Delphi 3 or something. Why do you think Delphi was so successful back then. I mean, it's obvious competitor with Visual Basic.

Lots of credit goes to Visual Basic, for sort of inventing the GUI RAD tool and I think that was fantastic. But Visual Basic had all sorts of issues. I would say, it was in many ways popular in spite of the fact that it was basic. There was a market there for more industrial strength language with a real compiler, native code, real modular compilation, and blah... blah... blah... And we sort of married, if you will, the RADness of that with a real compiler and then a great extensibility model that allowed people to build new components very easily. If you remember Visual Basic, for example, did not support inheritance and you could not create new components by inheriting from other components. In fact you couldn't really create new components in Visual Basic to begin with. You had to write them in C using a very complicated SDK. Where Delphi was written in itself and that was actually -- it was a dog fooding experience.

Yeah, that's always useful if you can do that.

Yeah, yeah.

So, what were some of the language features of, I think it was called Object Pascal at that time. It was obviously object oriented but there was also this component property event kind of thing. Can you elaborate on that a little bit?

Sure. Object Pascal introduced the three cornerstones of Object Oriented Programming: Encapsulation, Inheritance, Polymorphism. But it did not really have a system for writing components and components is one of those words that can mean anything. But it did not have a great model for creating visual components that sit on a tool palette. That you can drag on to a form and then manipulate properties in a property inspector and write code behind events. And that was in a sense Delphi's contribution to Object Pascal. The fact that we gave first class treatment to properties and events in the language. And that made it a lot easier to create these software components that pretty much every visual development tool has, today. It's still the same paradigm.

We'll talk about that later in the context of C#, but to wrap this Pascal, Delphi thing up: What's the state of Delphi today. Is it still in production? Is it still used?

It's still there. It's still used. I mean trackers show it but it certainly looks to be on the decline. Borland still sells, well it's now CodeGear, but I have to say that Delphi user community, it's an amazingly strong user community. It's still a great Windows client tool. It really is.

It's .NET now I guess.

They have a .NET version. Although I do think that most customers probably still just write native Windows apps or maintain existing native Windows apps.

I have heard a rumor that the Condor Soaring Simulator is actually written in Delphi, but I have to follow this up, I don't know.

I wouldn't know, yes.

That would be a strange use, because it's not at all forms Windows GUI kind of thing --

There are a lot of vertical segment windows client apps written in Delphi. More often than not you run across them and yeah like you said, medical systems is what you said. I mean that's like I've seen many of them.

Okay, so let's transition a little bit to let's say, at least your more contemporary stuff. Actually in the beginning of interview, I completely forgot to ask you to introduce yourself. So why don't we combine that, so you introduce yourself, and tell people what you are doing today.

So, my name is Anders Hejlsberg and I am a technical fellow at Microsoft. I work in the Server & Tools Business Unit, and more specifically in the Developer Division where I am the Chief Architect of the C# programming language and also sort of the Chief Languages Strategist, if you will, for Visual Studio languages.

C#, many people said or say is basically a cross between C/C++ kind of things and the Pascal/Delphi world. So can you explain a little bit how Delphi influenced or influences C#.

Well, you learn from your mistakes and your successes and if something works you keep it and if it doesn't, you get rid of it. So in some ways C#, was the language I worked on after Delphi at different company: at Microsoft instead of at Borland. And certainly something that had worked very well for Delphi was this formalized notion of properties and events. And I felt strongly that paradigm or programming with properties and methods and events had become common enough that it ought to have first class treatment in the language. And so that was one of the core designed tenets of C# was having properties and having events, as first class notions. As opposed to Java, say where you have a pattern-based approach. And you sort of have to squint to see the properties and ignore the get and set and the paran's and the methods and so forth.

And you don't have events at all, I mean you don't have --

Right you have listener interfaces and whatever all sort of pluming instead.

Yeah. You probably know the The Java Posse Podcast. Maybe, maybe not, or well you probably don't.

I have listened to a few of them.

That, they have this guy, Joe Nuxoll from Apple, and he is this great properties/event guy and he wants to put that into Java by all means.

Right. Well I mean, there's the whole debate now in the Java community about closures. Which really is sort of like the underpinning of it, if you will. It's function pointers or method pointers, if you will, which C# has had from day one.

The syntax has been getting nicer over the versions, you can delegate, blah, blah blah; now you can have real more or less Lambda expressions.

The syntax for writing them. But the underlying concept of a method pointer or a delegate or a method reference, this has been the same throughout. Although generics makes it a little simpler to declare them, because you can sort of declare one that's generasized, and then just use that.

So C# today: We had a discussion with Erik Meijer on LINQ. So I think that's probably one of the most known current new features of C#, and the stuff that is kind of hyped. Is there other stuff, I mean in the positive sense --

Yeah, yeah, okay! oh there is a positive sense

Okay, I'll retract that for you. That's talked about a lot. So, is there other stuff in current C# versions that you think is innovative compared to traditional languages? What's interesting for people to know?

Yeah, I feel pretty good about C#'s evolution. I think it's been it's been very innovative in its various releases. I mean 1.0 was sort of the baseline release then. But nonetheless that's solidified things like properties and events as first class treatment. The unified type system where in C# everything is an object. And then later you can start sort of taking apart the particulars of value types versus reference types, but they ist sort of this great unifying concept that anything is an object. And then in C# 2.0, we added generics and these are reified generics as opposed to Java's erase generics. Which I think, history clearly has proven what's the right approach. I'm very happy with that work, and that was great work done by Don Simon, Andrew Kennedy from Microsoft Research and now in 3.0, we talk about LINQ, because that's the headline, but the interesting thing about LINQ is that - first of all, it is built on top of generics and generics is the deep enabler for LINQ.

How is that, I don't see the connection?

Let me talk about and then we will come back to why it is. But LINQ is actually an amalgam of language features, about six or seven language features that come together to form this higher unity. So there are things in there like Lambda expressions, like anonymous types, local variable type-in, for instance extension methods, object and collection initializers and so forth. And then query expression or comprehensions, that we sometimes call them. And all of those come together to form this concept of language integrated query. But the thing that's interesting is that each of those features in and of themselves are quite innovative and quite useful.

Right, I knew of some of them, but I didn't put them under the LINQ money --

No, that is in a sense what LINQ is. LINQ is built out of those, and really the way LINQ came about - it's an interesting story. Because I've always been fascinated with the impedance mismatch - if you will - between general purpose programming languages and databases. And the fact that here are these two, in and of themselves incredibly powerful worlds that are so different. And the way they marry is so horrible. I mean it is like there's all this beauty in general purpose programming and all this beauty in the relational algebra and databases. And then you put them together with these horrible APIs. There are these queries and strings. So I always felt like there's got to be a better way. And, of course, one of the key, key enablers there is this notion of query. And I always felt that it was bizarre that you had this incredibly powerful query engine that only could be used on data stored in the database. But we have lots of data in memory arrays and XML documents. But the way LINQ sort of originally then got introduced in the language in our prototypes was just by hard coding syntax like where and select and what about new keywords and that compiles into certain library functions and whatever. But then we sort of gradually discovered that we could generalize this down to just discrete language features out of which, you get the bigger whole. But then it's often this way when you're doing new stuff in a language or any innovative field for that matter. You plow forward with a prototype and then you discover that the prototype is actually just an instance of a class of solutions. And then if you have the courage you back up and you put in place the class instead. We did actually do that, and at one point in the project we literally stopped. We took all of that stuff out, and then we put in more general concepts like Lambda expressions and extension methods and so forth. And then we built it all out of that instead. And that was well worthwhile. Now, you asked why generics? Well, generics make the type system much, much richer and it allows us to flow type information through complicated expressions. In LINQ when you write queries, you are really just sort of - in a fluent fashion - dotting together operator, should, where, select, blah...blah...blah. These are all generic methods that take type parameters. And then the inner play between the arguments and the way the types flow from the arguments into the results and then become the input to the next operator, that's all powered by generics. If there were no generics there, it's like in order to write a generalized 'Where' operator, well it would take, I don't know, a function that takes an object and returns the objects. You would have to cast everywhere. And then very soon, it would no longer look like a query language.

The other thing is probably the type inference that if you're able to --

Oh, yes, you have got to couple it all to -- yes, you don't want to manually have to say the types and of course this is why also in functional programming languages that there's so much type inference because otherwise it all, -- you know!

And there was one of the early examples I saw of LINQ that you did a query and then there was the result which was basically a statically type inferred compiled anonymous type which you could access with a dot operator. You had code completion and everything. But you never ever set what type it was, because it was anonymous. It was basically assembled from the future select.

Yeah, so the type flows out of the query and into the foreach that consumes the type down below.

Very nice. The other thing that I think is fascinating modeling is that it's basically built in metaprogramming facility that you can get the AST and do something with it. That's something I think that's not very well known. Or let's say that's not on the forefront of what people talk about.

Right, it is again one of these enablers. When you think about-- like if you really want query to be a unifying concept, where you write your queries in one way and then the execution infrastructure decides how to execute. Well sometimes execution isn't even going to occur on this machine here. It's like in the case of OR Mapper, you want to take the query, turn it into SQL and put it in a database. Or turn it into - I don't know - some web-based query language and send it to Flickr or Amazon or whatever you're writing a LINQ interface to. In order to do that you could argue that well maybe we should like reverse compile the IL for the predicate expressions and whatever that the user wrote. But that would be horribly complicated. IL is not a very user friendly format to grok expressions in. Hence, there was a need for sort of a formalization of expression trees.

Since you mentioned before that you're the chief language guy, we have to talk a little bit about language design issues. One thing we already talked about was this notion of components. So I don't think we have to revisit that. Another thing where I know that you have a very dedicated opinion about is exceptions, checked exceptions. So are they good or are they bad?

Let me answer in two ways. I completely sympathize with the intent and the desire to have stronger type checking, I mean in general, type-checking or stronger compile time checking is a good thing.

Okay, that answers another question I have for later.

As long as it doesn't get in your way. And part two of the answer is that I think when you weigh the pros and cons, it's not clear to me that you've made it better in the aggregate. Because checked exceptions have all sorts of problems with this notion that you must either handle or yourself in your method declare that you re-throw all of these or push on these exceptions. Of course, and again if you look the Java Closures Proposal for example: It's yet another example of how checked exceptions just really make your world painful. And so maybe the dial was dialed up too high. And so we certainly felt that the solutions we knew of that we could put in place in C#, did not - in the aggregate - make it a better place to program. And so we remain neutral on that. We do not have checked exceptions. That's not to say that we don't look at having tools like FxCop and whatever that could do, some analysis on your code and figure out whether you're handling all the exceptions and so forth and that's something we continue to look into.

That's a good point, that's more like the middle ground. Right, you have a system that allows you to trace what's going on with a tool but you don't require --

Right.

This plays also into this general trend of having more and more powerful static analysis tools with your language.

Yes.

Another thing that I wrote down is that I think - if I look at C# and also at Delphi - you are a big friend of making your intentions clear by specifying things like virtual override. So that you can crosscheck whether actually things fit together.

Yeah, again actually I think that a design we got right in Delphi and that was carried forward into C# is this notion that you must specifically say that you are overriding a virtual method. Like if you contrast it with C++ or Java. Or at least in Java, you override a virtual method just by saying the virtual (first of all, you never say virtual, everything is virtual by default, which I also don't agree with) but you override the method simply by restating. And it's just the coincidence that you use to same name and signature means that it's an override. And that is effectively sort of a versioning time bomb because as the base class evolves, it is likely at some point to introduce a method with the same name and signature as a method that exists in a user derived class that was written before. Now all of a sudden that becomes an override. But there's no guarantee that the semantic intent was the same here. And so now all of a sudden you're going to get calls to this method that you never expected to get. Or worse, you're going to get compile-time errors because the signature matches but the return type doesn't. And this has indeed happened as the Java libraries have evolved, you know this versioning bomb has gone off.

How does the override mode -- what if I prevent that, I mean, because if you just write override - well, okay see. First you cannot write override when at the time you write that there is the --

When you say override, there must be something to override or else you get a compile time error.

Right.

If you don't say override then you introduce a new method here and this method may have the same name and signatures as one you inherited, but then you're just hiding that one, you're shadowing it.

Are there other examples in languages of this kind of things, where you specify - with certain keywords or modifiers - was actually is going on? So that these kinds of things cannot happen?

Well for example, the way we treat interfaces and interface implementations in C# also makes you be a little more specific about how you implement. For example, we support private interface implementations where you can specifically implement this method of this interface by saying ..

Oh that's if you implement many interfaces in a class once in a while--

Right and they so happen to have a method with the same name and signature and in Java there's no way to have these two implementations. And that also does happen and it's also an example of sort of a versioning problem. So we try to - in the design of C# - think a lot about making it versioning resilient. Because it's one of those things that makes the language live longer. It's the kind of thing that doesn't matter at all in V1. And then - as you come down like ten years later - it matters a whole bunch. Because there are big codebases and you have not painted yourself into a corner with respect to introducing new features.

I think a good example of seeing some of the consequences of that is the Eclipse Platform. It's written in Java and they have all kinds of evolution nightmares. Blah... blah... blah... interface such and such 2, 3, 4. And obviously not everything is a consequence of those missing features --

Yeah, I mean with interfaces in general you cannot introduce new methods because --

Sure, but it's also other stuff, it is also implementation. It shows there's a platform that is very long lived and they really have a challenge of handling the evolution of the things without breaking old stuff. So let's look a little bit at languages of the future. Since you are the strategist, you have to know what they are.

Oh I would, if I knew the answer.

So one provocative statement I've read several times is: 'as long as it looks like C'. So you can invent any language you want, you can invent any language feature you want, you have to use curly braces. Of course that's a little bit cynical but where do you think --

Who made this statement?

I don't know. It might have been Steve Yegge in one of his -- I am not sure.

Okay.

So what do you think are important concepts in upcoming languages?

Well, I don't think the curly braced nest of languages is going to. And certainly, you look at languages like Python and say F# and whatever - and there are precious few curly braces in them. I do think that if you look at what is the underlying trend of programming languages, if you go back like all of these to what 40, 50 years that we've had them now. It's really the one thing that continues to happen is that we increase the level of abstraction of our programming languages. We started with plug-boards and then machine code and assembler and then C and then C++. And now we're sort of in managed languages like .Java and C# and dynamic languages are seeing a resurgence and whatever. So really, I see no indication that, that is changing. Meaning that really the next thing is going to be some upping of the abstraction level. Again, the challenge is identifying what that new abstraction is going to be. And that's sort of largely influenced by what's happening in the industry today. Which is that -- Moore's law has not stopped working, but it's changed in nature in that it's not going to give us higher clocks speeds anymore. It will still continue and everybody thinks that for at least another 10, 20 years to increase density and capacity, the human capacity.

The overall power.

But it comes now in the form of more CPUs instead of faster CPUs. It's really sort of like the bottom line. That means all of a sudden concurrency is so much more important than it used to be. Concurrency has always been important in certain domains like high-performance computing and whatever and graphics processing. But now it's starting to actually become important to mainstream computing because it is the only way that we're going to 'harness the power' so to speak. Of course, as a programming language designer that means that we need to think deeply about how we can do better models for concurrency. Because I firmly believe that the models we have today do not scale to general masses of application programmers.

I obviously agree and I think everybody agrees more or less except for the Erlang guys; Is one reason why concurrency is so complicated today that it's not part of the language but rather part of libraries? So it's hard to check, hard to -- and the compiler can give you only very limited support. You have a lot of protocols you agree to as opposed to having formal specifications of them.

Yes. I think the big killer is state. Or rather mutable state. And we have effectively taught programmers like generations of programmers that, "Hey, state is wonderful and you are free to mutate it, whenever you feel like it." Like, "Hey, declare yourself an array and then just start poking elements in there, in 'for' loops and what have you". And that's fine as long as everything executes serially, there's no problem. Then along comes concurrency and parallelism and all of a sudden, you have multiple units of work. You are mutating the same state and you can't even begin to reason about it. There's very little in our languages that provide the necessary framework for reasoning about it. So in essence you could say, yeah it's because it's a API although -- I mean we do have locks or synchronizations as language features but they're very low level feature.

Yes.

We do not have higher level concepts like this thing is guaranteed to be isolated or this thing is concurrency safe whatever or this function is pure or this object is immutable. A lot of these things are not language concepts. And ideally they should be but we don't necessarily know how to make them. I mean you could argue some of them we know what a solution might look like. There are pure functional programming languages and they are indeed wonderful for concurrency. They're just not so wonderful for writing real applications. So that isn't the answer either but we can borrow some from there and there are certainly parts of applications that don't need to be as mutable in their state management as they are today.

At QCon two weeks ago, I saw Ted Neward talk on F#. And then Simon Peyton Jones talk about Haskell. And they both, of course, are functional and ideally more or less pure functional. And they, of course, also talked about the fact that this is really great for concurrency. I've heard many other talks that basically had the same message. But what I haven't heard, yet, is a talk that tells me, "Okay, here's functional stuff and then there is the other stuff that has side-effects," because at some point you have the side effects. So what do you implement with which of those? How do you distinguish them? How much concurrency do you put in infrastructure/ architecture/application servers and stuff? How much is necessary on the language level? Like if you look at Erlang for example. The fact that it's functional is not really important. The reason why it is so good for concurrency is because it has this actor model. It would be no problem if you had imperative and shared state within an actor.

Right, as long as it's isolated.

Yeah, but that's the whole point of actors!

Right exactly. So Erlang formalizes the notion of isolation or goes further in formalizing the notion of isolation. And once you have an isolated domain then sure, you can have mutation in there to your hearts content. Because you're guaranteed that there's only one threat of execution at a time. It's stuff like that where we have to -- but then this doesn't really work. This doesn't help you if you're writing a data parallel application that's going to do matrix, multiplication, or whatever. So there are many different forms of concurrency if you will. And we need to sort of push the state-of-the-art there in coming up with programming models that are more suitable than what we have today. And then after that comes then formalization in the language of those programming models. In essence, one thing that gives me hope is that with all of this stuff that we've done in my domain and in C#: the language actually has become incredibly rich. And you can start experimenting with concurrent programming models simply by writing APIs. And APIs have become rich enough now that you can almost create little domain specific languages just as APIs. Now LINQ is an example of that. We have another example in the Thread Parallel Library or TPL that our concurrency group is building. They're actually building two technologies together; TPL and PLINQ, which is a parallel implementation of LINQ. And they're just APIs! But they're very rich APIs that take advantage of generics and type inference and so forth and through those it's almost like you can introduce new statements like Parallel.For(), it's really a function but you pass to it the body of code you want to execute. So in essence, it's like a statement.

So what I understand from that is that in addition to solving the concurrency challenge in future languages, I think having them more expressive maybe through means of concepts borrowed from functional programming and first class functions, and sozial stuff is another probably important --

Well, it's important because it allows -- if you try to build a new programming model for concurrency by noodling with the keywords in the language and then you try to do all of the language work upfront. Well you have a couple of problems. One is you might get it wrong and now you put some stuff into the language that you can never get rid of again. And now you've aged the language and the language will therefore become irrelevant, sooner. And that's a problem. Problem number two is that there's only you thinking about the problem not your entire user community. The other way around, instead of adding the instance to the language, you add the class that allows the users to create the instances so to speak. Then you get a much broader user community experimenting in the field. And you can then in sense as a language designer cherry pick and go: "Wow, this thing is becoming very popular. Maybe we should think about having formalized comprehensions or statements that are just a pattern over that API". Like foreach is, for example, in C# it is just a pattern over using enumerators and LINQ expressions are just a pattern over the LINQ API pattern. So that's sort of what I think is the better way forward if you will.

So that also hints in the direction of metaprogramming/domain specific languages?

Sure.

Before you said that you are a fan of static typing, you didn't say it explicitly, but it became quite obvious. So how do you think metaprogramming/DSLs goes together with static typing. I mean most of the internal DSLs can be seen in dynamic languages like Ruby.

Well, it's interesting because-- people are just like a little tangent there. I think one of the reasons that languages like Ruby for example, or Python are becoming popular is really in many ways in spite of the fact that they are not typed. But because of the fact that they do very good metaprogramming support. Static typing: I don't see a lot of downside to static typing other than the fact that it may not be practical to put in place. And it is harder to put in place and therefore it takes longer for us to get there with static typing. But once you do have static typing, I mean, gosh, like "Hey, the compiler is going to report the errors, before the space shuttle flies instead of whilst it is flying," that's a good thing. You get productivity tools, like statement completion, which if I were to take that away from programmers today there would be there -- I mean I would be dethroned immediately and then someone else would be put in place. And they'd have to reinstate it, because it is such a productivity tool. And better refactoring requires better knowledge of types. Static program analysis, and whatever. Like performance optimization blah... blah... blah... I mean there's a long laundry list of things that static typing is the enabler of. So I continue to think it's important. Now with respect to DSLs, I don't know. We think a lot about DSLs are and I think they're a bunch of things we've already done in C# 3.0 that make it a better place for creating DSLs. Like expression trees is definitely an enabler there. And we will look at growing expression trees into becoming statement trees where you can express full method bodies, if you will, as trees and pass them around as arguments and manipulate them and so forth. In many ways, I think it's important for us to work on creating a better ecosystem, better APIs, better infrastructure for dynamic program construction. People tend to think that there's all this resurgence of dynamic languages and we're becoming more and more dynamic you know. But we're actually doing very dynamic things with static languages. Look at something like ASP.NET for example which is huge dynamic programming system. You drop an .aspx page into a directory and puff, someone notices that its newer. He goes, recompiles it, turns it into native code that then runs, but it's totally dynamic right. But the way we get their sometimes through code generators and whatever is somewhat complicated. We could have APIs that allows you to dynamically generate, statically typed programs. There's another interesting thing there which is this notion that we are all sort of wired in our heads to associate dynamic programming, with lack of typing and static programming with strong typing. And that doesn't have to be that way. And I actually think that the ideal place to be is static programming, but dynamically generated, if you follow what I am saying. I mean there is no reason why we should not do better type checking in a dynamic scenario as well.

Of course, I mean if you have this typical Ruby case where you call a method that doesn't exists and then you have 'method missing' invoked, or whatever it's called in Ruby. I don't know how to handle this, what should I do. You can't do this in a statically typed language, because the compiler wouldn't let you call this method, because it's not there. So you have to introduce some, let's say, type system holes like 'dot-dot' meaning, instead of 'dot' --

You could do it through 'dot'. Yah you're sort of pointing out that --- but I will first say that the fact that you sometimes want to do something dynamic doesn't mean that it should always be dynamic.

Absolutely, I agree 100%.

So you could certainly speculate about formalizing the notion of dynamic dispatch in a statically typed language. And that's something that I find to be very interesting and something that we might do in a future C#. Now we could do it through a special 'dot' operator or we could do it through static typing. We could say, if the thing you're dotting on is of a type that says 'I am dynamic,' then --

-- implementing the dynamic is this a better interface or whatever --

Then the dispatch is dynamic. So again static typing actually allows you to do different things for dynamic dispatch.

That's really interesting that you're thinking about the stuff. Because that is stuff that -- I'm really interested in Scala, because it feels almost like a dynamic language for a brief type interface and stuff --

Yes, yes

--but it doesn't! It is not dynamic, because I am not a fan of dynamic languages, but still a very interesting discussion.

Yeah, not this is -- I mean I think one of the examples that people cite in C# 3.0 is local variable type inference and the fact you just say, var x = something and it looks just like JavaScript, but it is actually strongly typed.

So, to come towards the end slowly but certainly. You said before that if somebody takes away the statement completion feature then I'm basically screwed. So I think one really important cornerstone in future language development is that there is no point in developing a language without thinking about the tool that you use to work with the language. So can you talk a little bit about, except, well in addition to the statement completion and refactoring which is, kind of, obvious how language design might change in the future when we take into account the tooling aspect as a first class ingredient to language design.

That's actually a very fascinating area and I've always been a strong believer in symbiosis between tool and language and framework.

That's the third ingredient.

That's sort of the -- and in a sense if you look at like Turbo Pascal. I mean it was about more tightly marrying those, and then that was really what fueled its success. And that's how all modern IDEs look today. I think it's foolish to think about one to the exclusion of the other. Because in our day to day lives, as programmers we don't really sit there and make a distinction between whether this is a keyword or an API or whether I mean it's important for this to be deeply, deeply integrated. Now what were you asking about -- how does it affect language design.

Or does it or it doesn't?

Well, it absolutely does. Here is a good example with LINQ, and it is very, very relevant really. If you program with LINQ, you will have noticed that the select clause in a query comes at the end of the query. You say from blah.. blah... blah... where, order by group by blah... blah... blah and then finally end with a 'select'. Now there are certain API reasons why that makes sense because the 'select' is the last thing you do. But we could have certainly in our query comprehensions put the 'select' clause first like SQL does --

Yeah, 'select', field one, two three, from --

Select blah... blah... blah from blah... blah... blah. But think about what the statement completion experience for that would be. Now here I am typing "query = select space"

Right, if you don't know from what --

What do we show you - everything that's known to mankind, or? We have no idea where things are coming from yet. But if you say from blah... blah... blah... where-- now we know what's in scope! So we can show you what. And so that was one, to us, a deep motivate actually for putting things in the other order, if you will. VB 9.0, in its original prototypes had the 'select' clause first. And they did run into this statement completion problem. And effectively you'd have to write 'select' and then you'd sort of have to write 'from' blah... blah... blah... and then go back to the 'select' and now you could get statement completion, It didn't work so well.

Very nice example, yeah. So another thing that I always think of but I kind of really, probably can't put it in words, is: Somehow if you have a static language which supports metaprogramming kind of things that the IDE would have to understand all that stuff to a much deeper extent, so that it could actually understand what you just metaprogrammed, so that you could take into account, and the compiler knew that, I don't know. I think it makes things more complicated.

Absolutely it does and then there is -- I am fascinated by DSLs but there's a part of me that also worries about DSLs. Because today we have to deal with one language not a thousand languages. Like in essence with DSLs every program becomes its own language right then and that could be dangerous you know for a --

Or at least the domain.

Well, depending on how easy you make it and how much you push it on whatever show. There's is soap. It's, yeah, it's a tricky issue.

So to wrap this thing up, do you want to mention a couple of interesting upcoming C# features? First published on SE Radio, no, no, no I mean but the road map, is there any?

Well I think in general, I can tell you that about that the big influencers and we've already talked about them. Concurrency is huge and we're going do something. I don't know what the something is, but we are definitely thinking about it. Domain specific languages, metaprogramming, whatever, you've already seen us take steps there and it's an important influencer and dynamic languages are important. When I say dynamic languages, I don't just mean like Python, Ruby and whatever, I mean dynamic styles of programming. And that has lots of impact on C# as well or will have impact on C# as well. But exactly what the features, look, I couldn't tell you because I don't know yet.

Okay, that's fair. Okay, anything else you want to leave our listeners with, any pearls of wisdom?

Nothing comes to mind right now, but other than, as usual. We live in interesting times. And you would think by now that, that we'd be done. But the challenges just seem to get bigger all the time.

That's a good thing. The bigger the challenge people want us to write software for --

Yes, yes. All we can hope is just that, that we don't sort of fall victim to the old adage of, you knew that it couldn't be done and therefore you never tried.

Okay Anders, thank you very, very much for the interview.

My pleasure!



Syndicate content