Fabulous Adventures In Coding
Eric Lippert is a principal developer on the C# compiler team. Learn more about Eric.
Well, I intended to spend the last three weeks blogging about C# design process in anticipation of our announcements at the PDC, and then I got crazy busy at work and never managed to do so!
As I'm sure you know by now, we have announced the existence and feature set of that hitherto hypothetical language C# 4.0. Of course I'll be blogging extensively about that over the next year; today though I want to pick up where I left off last time and talk about the tragedy of Object Happiness Disease.
OHD is a disorder believed to be related to Thread Happiness Disease, the belief that threads are awesome and that you should therefore make as many as you possibly can. OHD is an even more common condition which afflicts developers at all levels of experience. Symptoms of OHD in C# developers include:
In short, the Object Happy believe that object-oriented programming is a good in of itself and that OOP principles are objectively (ha ha) good principles.
I don't share these beliefs.
Now, don't get me wrong. I believe that OOP is frequently useful. In fact, it is frequently the best available tool for a great many real-world jobs. OOP works particularly well when you have:
And that is where its goodness comes from: OOP techniques make real people more productive in solving real problems and thereby creating value. The techniques are not good in of themselves, they're good because they're practical.
Perhaps surprisingly, our goal in making C# is not to make an object-oriented language. Our goal is to make a compelling and practical language for general-purpose application development on our platforms, and thereby enable our customers to be successful. Making an object-oriented language called C# is just a means to that end, not an end in of itself.
So, yes, the oft-heard criticism that "extension methods are not object-oriented" is entirely correct, but also rather irrelevant. Extension methods certainly are not object-oriented. They put the code that manipulates the data far away from the code that declares the data, they cannot break encapsulation and talk to the private state of the objects they appear to be methods on, they do not play well with inheritance, and so on. They're procedural programming in a convenient object-oriented dress.
They're also incredibly convenient and make LINQ possible, which is why we added them. The fact that they do not conform to some philosophical ideal of what makes an object-oriented language was not really much of a factor in that decision.
Here's another way to think about it.
I had a discussion with Jim Miller a while back about the meaning of the term "functional language" in the context of Scheme. To paraphrase somewhat, Jim's position was along the lines that a "functional language" is one in which the design of the language makes it easy to program in a functional style and difficult (or impossible!) to program in a non-functional style. For example, Scheme does allow mutation of shared state -- a very non-functional-style feature -- but the convention in Scheme is to call attention to the fact that you are doing so by marking mutating functions with a "!". It is possible to program in an object-oriented style in Scheme, but the language resists you at every turn.
I certainly see the merits of Jim's position, but I take a weaker stance. When I say "functional language", I mean a language in which it is possible without undue difficulty to program in a functional style. I do not require the language to work against you if you try to program in a non-functional style in it. For example, I would call JScript a functional language. It is certainly possible to program in a non-functional style in JScript, but you can also treat JScript as Scheme with a slightly goofy syntax if you really want to.
I think about "object-oriented language" the same way; C# is an object-oriented language not because every feature of the language strictly adheres to OO philosophy. Rather, because as a practical matter it is possible to program in an OO style in C# if that's what you want. Adding features that enable other styles of programming does not make C# less of an OO language.
Next time, I'll talk a bit about the "theme" of C# 4.0 and how that influenced the design process. (And if you absolutely positively cannot wait to hear about some of the new language feature in detail, try my colleague Chris Burrows' blog.)
I'll just say one thing that should get an educated reader critique everything written as this was done 15 years back:
requesting that multiple class inheritance be added to the language
I used to have this symptom very bad, but thankfully with many years of c# therapy i've been cured. for the most part at least.
Some days are harder than others . . .
int19h> TypeMock looks interesting. It's an interception system using the profiler API, so I guess it slows things down, but that doesn't matter in a unit test scenario.
Ah... Multiple inheritance... I would gladly stop requesting that if I had a proper way to make mix-ins.... Right now, having a class that implements two interfaces, reuses default behaviour from both, and redefines some from both, is complicated. An OO language should make that simple, you said this yourself !
Regarding object happiness ... in my opinion, the true power of Linq comes not from functional programing alone, but from the fact that it can convert functional constructs to "Objects" ( Expresion<Func<...>> are objects).
How I see it is that, Objects are more flexible than functions, while functions are closed black boxes in most cases, objects are boxes with windows and doors. Generaly functions are composable, while objects can be both composable and decomposable, this is why I'm somewhat object happy in general, but I still like a functional approach where decomposition/modification is not needed or should be avoided (and very much welcome the functional aspect of C#).
Dynamic? can't say I'm I have a opinion about it yet, as I'm not a dynamic fan, maybe I would have liked more some Spec#/C(Omega) features at first sigh, but hey :) there's a place for everything, in a dynamic world (literally) even a statically typed language can make a good use of dynamic features. I'm really curious to see how dynamic will work with generics, extension methods, lambda expressions and especially Linq.
Dont forget that there are more ways to regard objects.
Personally I use ruby, so I am much more inclined to the dynamic ways of smalltalk. I even enjoy prototype thinking in objects.
For me essentially, OOP is finally about messages mostly (that alter a state), then come the objects. I always felt that C++ overcomplicated the whole aspect behind it to the worse. The only amazing thing is that C++ was such a success compared to C, because we still see so much of C++.
This, in a way, makes me sad, because frankly C is a huge mess, especially with the whole ecosystem.
> For me essentially, OOP is finally about messages mostly (that alter a state), then come the objects. I always felt that C++ overcomplicated the whole aspect behind it to the worse.
Glad to see the Smalltalk "that's not what I meant when I invented the term 'OOP'!" mentality is still alive. :)
Do keep in mind though that the very first OO language was still Simula, which was very much statically typed and static overall (and C++ and the rest of the family are all recognizable descendants of Simula).
What do you mean by decomposition in this context?
I mean that objects are inherently mutable, objects can be composed of more objects as fields (that are exposed or not) and if the object pars are exposed and mutable, then the object is decomposable, on the other hand when you compose functions you create a new function that is a black box, you can't get to it's inner parts (usually).
Welcome to the 47th Community Convergence. We had a very successful trip to PDC this year. In this post
Welcome to the 47th community convergece. we had a very successful trip to XBOX this year in this post
Sorry I'm late. Don't sweat it if no one reads this (OO humor).
The number one problem I've had with all Microsoft products to date (with one exception) is this: too many features!
I've been a professional engineer/programmer/etc. for 25+ years, and I've used a fair variety of Microsoft products over the years, as well as non-Microsoft software development products.
Please, please, PLEASE, if anyone at Microsoft reads this, consider changing your mind! Rather than continuing to generalize C#, give us more, more specialized, tools! The more you generalize C# the less useful it will be for me to solve problem X.
I have used a screwdriver as a chisel. It worked great! Once. But after that it only worked as a chisel. Now that I'm a little older I use the right hand tool for the job.
I forgot to mention the good news! Sorry. My favorite computer ever (in the 25 years of using personal computers -- literally! I still own several CP/M machines which I never use).
I use an NEC MobilePro pretty much every day -- at work, at home, at church, in the car (just audio while driving, of course), at the local coffee shop after walking 30 minutes to get there, etc. That's Windows CE 3.0, which of course is my favorite single operating system ever, for mobile computing. I honestly do not need any of the additional features since, and still VERY MUCH MISS the lack of VBscripting in that one!
Kudos to KISS.
"The techniques are not good in of themselves, they're good because they're practical."
You've actually touched upon a serious philosophical here: "inherent value" is nonsense.
Value is a relationship between a valuer and an object; it is not an inherent property like dimension or mass. For something to have value, there _must_ be a valuer.
Thus a software methodology is _in of itself_ utterly devoid of value. It might however be valuable to certain people in certain contexts. The same applies to everything in existence - trees, rocks, computers, buildings, paintings, music, even people unless they (or others) see value in themselves.
Very good resources for the coming version... Sam Ng Dynamic in C# Part One Dynamic in C# Part Two Chris