Peter Bright has written a multi-page post on Ars Technica explaining the myriad technical failures of Microsoft’s tools strategy that have driven him off the Windows platform and over to OS/X. It’s just been slash-dotted and is getting the predictable level of commentary from the nominally MS-bashing crowd over there.
Ok, let’s leave aside for the moment the simple fact that if Mr. Bright was free to drop Windows and move over to OS/X he’s not working on anything that matters very much. I mean that he doesn’t have a lot of people depending on what he’s doing, otherwise he wouldn’t be so free to make that choice. Whatever. If he’d rather work on a Mac then who the hell am I to comment? But along the way he feels the need to rant a little on the “miserable” Windows development experience on .Net, and that’s where he goes straight off the rails.
Not that he was really on the rails to begin with. Before getting to his laundry list of .Net’s weaknesses Mr. Bright felt the need to categorize the world of software developers according to his own schema. In that world, there are three types of programmers: Excel-wielding macro-cowboy pseudo-coders in business suits; lazy, uninspired cube drones writing clunky, misshapen enterprise applications that nobody really cares about; and those conscientious, intelligent, detail-oriented super coders like himself. Hilariously, he characterizes that last group as the people who might use C++ or “whatever beret-wearing funky scripting language was à la mode at the time.” Like anyone who uses C++ regularly considers a funky scripting language to be real programming (“Look, Bjarne! Anything can be an object!”). Hey, if we push hard enough maybe we can cram the mainly gray-haired, uber-serious C++ programmer community into the same can with all those cool, messy-mopped script-slinging web-onauts. Maybe, but I doubt it.
With the offensive part of the article out of the way he can finally move on to the real weaknesses of Microsoft’s strategy. The first one is: Microsoft did nothing while Apple bought NeXT. According to Mr. Bright in 1996 there was XP and NeXT, and Microsoft hasn’t done a thing since. XP is unchanged since 1996. Oh, wait a sec… Windows XP wasn’t released until 2001, five years after Apple bought NeXT. I’m not making this up. These are his own words…
The purchase of NeXT gave Apple a buzzword-compliant OS with a healthy ecosystem of high-quality third-party applications. Meanwhile, Microsoft was lumbering along with Windows XP.
Of course in the next paragraph he begins with “In 2001, when XP was released, this was not such a big deal.” So I take that back: I obviously have no idea what the hell he’s talking about. Windows XP is over a decade younger than NeXT, and the system we run today is hardly the exact same system released in 2001, but enough about that. Let’s get to some of those real weaknesses.
Because everything now has to live “within” the .NET world, .NET has to be all things to all people. Well actually, that’s not true. It’s trying to be good enough for the first and second kind of programmer. The third type—well, just ignore them. They’re too demanding anyway. They’re the ones who care about their tools and get upset when an API is badly designed. They’re the ones who notice the inconsistencies and omissions and gripe about them.
Well, at least one of them does. Leaving the briefly recurring elitist stereotyping aside, what is he comparing the framework to? Java? Well, I hear that, brother. It’s a good thing Java isn’t dumbed down and palatable to every kind of programmer writing every kind of application on every kind of platform. Ahem.
One practical manifestation of this is that .NET reflects a lot of the bad decisions made in Win32. For example, .NET provides an API named Windows Forms for writing GUIs. Windows Forms is based heavily on the Win32 GUI APIs; the same GUI APIs that owe their design to Win16.
Does WordPress have a WTF quicktag? Windows Forms is heavily based on the Win32 GUI APIs? Well only in the sense that it has to draw stuff… like windows. Somewhere deep inside, on XP anyway, Windows Forms have to get a device context and paint rects. Other than that Windows Forms resembles Win32 the same way I resemble Brad Pitt. And on Vista the WPF doesn’t even use GDI+ to draw anymore. It uses a brand new rendering layer based on Direct3D. What the heck is he talking about? I’m sorry, I’m nearly repeating myself.
To properly write Windows Forms programs, you need to know how Win32 works, because there are concepts from Win32 that make their presence felt in Windows Forms. In Win32, every window is related to a specific thread. There can be multiple windows that belong to a thread, but every window is owned by exactly one thread. Almost every action that updates a window in some way—moving it on-screen, changing some text, animating some graphics, anything like that—has to be performed within the thread that owns the window.
I don’t quibble with the technical content, although it is a little less than earth-shattering news, but does Mr. Bright actually believe the average Windows developer needs to know how GUI thread management is performed in order to get real work done? Are we all champing at the bit to write multi-threaded GUI applications?
This restriction in itself is not entirely uncommon. There are very few truly multithreaded GUI APIs, because it tends to make programs more complicated for no real benefit.
Whew. I thought I was in trouble there for a moment. I certainly agree with the conclusion, but for the record the bulk of the .Net GUI API is thread-safe. Maybe he meant to say there are very few multithreaded GUI APIs other than .Net.
The problem lies in how .NET makes developers handle this restriction. There’s a way to test whether an update to a window needs to be sent to the thread that actually owns the window or not, along with a mechanism for sending the update to the window’s thread. Except this way doesn’t always work.
So it’s a good news/bad news thing. The good news is that almost nobody needs to write multithreaded GUI applications because the additional complexities outweigh the benefits. The bad news is the whole mechanism for testing which thread in your multi-threaded GUI application owns a particular Window is broken. To be honest I’ll have to take his word for it. I avoid multiple threads at the GUI like I avoid booth time at tradeshows. Is that it, then? No it’s not. There’s still the abomination of OpenFile to discuss.
For example, there’s a function called OpenFile. OpenFile was a Win16 function. It opens files, obviously enough. In Win32 it was deprecated—kept in, to allow 16-bit apps to be ported to Win32 more easily, but deprecated all the same. In Win32 it has always been deprecated. The documentation for OpenFile says, “Note: Only use this function with 16-bit versions of Windows. For newer applications, use the CreateFile function.” But in spite of that, Win64 still has OpenFile. No one should be using it, but it’s still there.
It’s there, yes. Do you have to use it? No. Does Mr. Bright have to use it? No. Does Mr. Bright know enough not to use it? Apparently so. Is it documented? Abundantly. Then exactly why is this a problem? Is Microsoft’s track-record on backwards compatibility so poor that we need to question them on it even when the techniques they use don’t impact us at all? I have some stuff written in C++ and assembler fifteen years ago that pokes the VGA hardware directly and it still runs on XP/SP2 today, so I’ll give them the benefit of the doubt on that one.
Is there anything else? Oh yeah, file sizes are still returned as two dwords rather than a quadword. Son of a bitch. I’m out of here. The conclusion?
So Windows is just a disaster to write programs for. It’s miserable. It’s quite nice if you want to use the same techniques you learned 15 years ago and not bother to change how you do, well, anything, but for anyone else it’s all pain. I thought before that Microsoft cared about people like me. But it doesn’t.
Wow. I… um. I don’t know. One sec. I need to step outside and catch a breath. Ok. Let me just say this: I was writing Windows applications fifteen years ago. In fact I like to think I wrote some pretty complicated ones. One of them was a backgammon game that used GDI and sprite-blits and neural networks in 1993 and is still being used in some corners of the Middle East and Europe today. I can tell you that the techniques I used to create the GUI are nothing… and I do mean nothing… like what I use on .Net today (which isn’t Windows Forms, by the way, it’s XAML and WPF). They weren’t even anything like ATL, or MFC. Windows GUI technology hasn’t been standing still. To suggest it has is almost breathlessly ignorant. I don’t mean to give offense here, but Jesus H. Christ, man, what in the name of God is he talking about? Now I am certainly repeating myself.
I admit I had to stop reading the article at this point. I’m not a regular Ars reader, and I don’t really know Mr. Bright’s work. He’s a digerati somebody, and I’m very much a nobody. I might even have sunk down to that clueless second layer of drones he keeps referring to, now that my kids are teenagers and I don’t have as much time as I used to. I’m sure Mr. Bright means well, and truly feels like the Mac is a better platform for him. That’s awesome. I applaud choices. I use Debian and Ubuntu and XP and Vista and in the future I’ll damn well use whatever will put Yuengling in the fridge. I thought MS-bashing had about reached its pinnacle when I started reading praise from certain quarters for Jerry Yang’s big wave-off on $34 a share that he (and his investors) will never see again. But this article sort of restores my faith that the heights have not yet been reached. And that’s all good, since it gives us something to write about.
>>>> “The first one is: Microsoft did nothing while Apple bought NeXT. According to Mr. Bright in 1996 there was XP and NeXT, and Microsoft hasn’t done a thing since. XP is unchanged since 1996. Oh, wait a sec… Windows XP wasn’t released until 2001, five years after Apple bought NeXT. I’m not making this up. These are his own words…”
Hm, not sure where you’re getting that from. Apple did plenty to NeXTstep. Never suggested otherwise. And they’ve kept on doing stuff. They’ve managed to produce core OS updates quite regularly, in stark contrast to the five year gap between XP and Vista.
>>>> “Well, at least one of them does. Leaving the briefly recurring elitist stereotyping aside, what is he comparing the framework to? Java? Well, I hear that, brother. It’s a good thing Java isn’t dumbed down and palatable to every kind of programmer writing every kind of application on every kind of platform. Ahem.”
The problem is that you seem to think that something must be dumbed down in order to be effective for a wide variety of skill levels. I don’t think that’s true. You don’t have to be “dumbed down” to be approachable by a wide variety of programmers solving a wide variety of problems. Concepts like “programming against concrete types” are, to me, “dumbed down”. Sure, you can do it in Java. Occasionally, you don’t have much choice but to do it. But in .NET, it’s not just an occasional unfortunate thing; it’s the norm. .NET’s interfaces are typically one of:
1) over-restricted, so they can’t be used (there’s a reason IList(T)–which MS describes as “the base interface of all generic lists”–is not implemented by LinkedList–you’d think the clue should be in the name there, a linked list should be able to implement the IList interface)
2) under-restricted, so they can’t be used (in Java, I can write vendor-neutral SQL using prepared statements, because Java standardizes how it does positional parameters and provides convenient mechanisms for filling them in; in .NET, I can’t, because it doesn’t bother to standardize how positional parameters work)
3) totally absent (why is there no ISet?)
So in .NET it’s mighty hard to program against interfaces. And yet, providing interfaces that *do* make this practical does not make anything any harder to use. Making it so that the people who understand about OO can program against interfaces does not prevent anyone from programming against concrete types.
We see this reflected more generally in the abstractions offered. .NET’s Enumerators, for example, are forward-only, read-only affairs. Want to back up in your enumeration? No can do. Want to modify the collection? No can do. Want to save your position in the collection? No can do. Let’s say you want to, for example, iterate through a list (and I mean any list, both array-backed and linked) to find a particular location, and then efficiently insert an item immediately adjacent. Can’t do it.
Compare and contrast this with C++’s iterators or Java’s Iterator/ListIterator pair. I can do that task in both of those languages efficiently.
.NET’s library might make the simple things simple, but it makes the hard things hard (because you have to start from scratch and ignore the library). Java and C++ make the simple things simple, but they also make some of the hard things simple, and I never have to totally disregard the library and start from scratch. They simply use better abstractions. This not only makes them easier to learn and use (I can learn a few basic concepts and apply them over and over, rather than having to learn each individual class on its own); it also makes them easier to use in a wider variety of scenarios.
>>>> “Windows Forms is heavily based on the Win32 GUI APIs? Well only in the sense that it has to draw stuff… like windows. Somewhere deep inside, on XP anyway, Windows Forms have to get a device context and paint rects. ”
Huh? HWNDs aren’t “deep inside” Windows Forms. They’re directly exposed on any Control. IsHandleCreated likewise. WndProc also. The mechanics of Win32 windows are totally in your face, and you actually have to care about them, because if you don’t, you can get things wrong.
>>>> “I don’t quibble with the technical content, although it is a little less than earth-shattering news, but does Mr. Bright actually believe the average Windows developer needs to know how GUI thread management is performed in order to get real work done? Are we all champing at the bit to write multi-threaded GUI applications?”
Actually, yes, I do, and they certainly ought to be. Blocking the UI to perform computation is terrible. How to avoid it? Multithread. Right there you have to start caring about how threading interacts with windows. This isn’t some terribly unusual esoteric practice we’re talking about here. We’re talking about spinning off threads that perform some computation and update the UI. Good grief, this is why MS has the BackgroundWorker class–because it’s so commonplace (and so errorprone) that they decided to encapsulate this functionality to make it easier to use.
In Windows Forms, it’s possible to create the message pump on the “wrong” thread, have controls attached to that thread, and for the thread to exit. I can’t do that in Swing. I can’t do that in WPF. But I can do it in Windows Forms, because Windows Forms totally fails to hide the mess that is Win32 from me.
>>>> “I certainly agree with the conclusion, but for the record the bulk of the .Net GUI API is thread-safe. Maybe he meant to say there are very few multithreaded GUI APIs other than .Net.”
.NET isn’t a multithreaded GUI APIs. BeOS had a multithreaded GUI API. I’m not sure of any others; Swing and AWT are single-threaded, Win32, WinForms, and WPF are single-threaded. What this means is that updates to the UI can only occur on one thread (the event dispatch thread in Java, the thread with the message pump in Win32/WinForms/WPF), and attempts to update the UI from other threads will result in undefined behaviour.
Consequently, WinForms isn’t, for the most part, thread-safe. Most methods on Windows Form objects can only be called safely from the message pump thread. This is why MS writes of System.Windows.Forms.Control, “Only the following members are thread safe: BeginInvoke, EndInvoke, Invoke, InvokeRequired, and CreateGraphics if the handle for the control has already been created. Calling CreateGraphics before the control’s handle has been created on a background thread can cause illegal cross thread calls.”. Everything else–and there’s a lot else–is not thread-safe.
>>>> “So it’s a good news/bad news thing. The good news is that almost nobody needs to write multithreaded GUI applications because the additional complexities outweigh the benefits. The bad news is the whole mechanism for testing which thread in your multi-threaded GUI application owns a particular Window is broken. To be honest I’ll have to take his word for it. I avoid multiple threads at the GUI like I avoid booth time at tradeshows.”
Then I guess you create lots of applications that lock up every time the user tries to do something that takes more than a split second to complete.
>>>> “Then exactly why is this a problem?”
Because it shouldn’t even be there. If you have an API that literally no-one on earth should be using, you should remove it.
>>>> “I can tell you that the techniques I used to create the GUI are nothing… and I do mean nothing… like what I use on .Net today (which isn’t Windows Forms, by the way, it’s XAML and WPF).”
Right, except XAML and WPF both produce UIs that are wholly non-standard, unlike WinForms, which is only partially non-standard. Or perhaps you want hardware acceleration on Windows XP (Swing can manage it, Win32 can manage it, but WPF? Nuh uh; you only get acceleration of that on Vista. Even though Sun has managed to get both OpenGL and Direct3D Swing acceleration on XP…). Or perhaps you need an HWND to pass to Direct3D or DirectShow or something.
But if you are using WinForms, it’s not “nothing” like what you use on .NET. It’s pretty much *exactly* like what you use on .NET. It’s the same API and it works in the same crappy way.
Thanks for dropping by, DrPizza. I don’t think I said that Apple did nothing to NextSTEP, but rather that Next and XP were not coincident in time. I think everyone knows it took Microsoft longer to get from XP to Vista than it should have, and I wouldn’t argue that point. I just don’t think Apple’s acquisition of Next provides any kind of reasonable counterexample.
>> The problem is that you seem to think that something must be dumbed down in order to be effective for a wide variety of skill levels. I don’t think that’s true.
Well, actually, I wasn’t saying that either. The point is that .Net is no more “dumbed down” than any other framework that aims to subsume the complexity of low-level APIs in higher level abstractions, and in fact .Net is much less dumbed-down than Java in my opinion. Some of the things the article complained about really represent handles that are there for experienced developers to use, that allow lower level concepts to peek through… such as the HWND properties that were complained about elsewhere.
I don’t disagree with the specifics of the shortcomings in the collection classes that were cited. They would have made better examples for the original article than some of what was presented, nevertheless they don’t come anywhere near making Windows a “miserable” platform for development. If the article’s initial premise hadn’t been so over the top and silly no response would have been necessary. Had it been titled “Shortcomings in .Net” I doubt anyone would have noticed.
>> Huh? HWNDs aren’t “deep inside” Windows Forms. They’re directly exposed on any Control.
Sure they are, but they aren’t necessary for 99% of Windows Forms programming. I don’t understand the obsession with the fact that the underlying system peeks out of the API in places. It’s only relevant to people who need to get at that stuff to solve a problem, and then it would be considered a strength that you can solve the problem at all.
>> Actually, yes, I do, and they certainly ought to be. Blocking the UI to perform computation is terrible. How to avoid it? Multithread. Right there you have to start caring about how threading interacts with windows.
Blocking the UI to perform computation isn’t anywhere near always terrible, and it’s that kind of blanket generalization from context-specific personal experience that got the original Ars Technica piece in trouble. Unblocking the UI while computation is performed is only valuable if the user can do something else worthwhile in the meantime. This isn’t always the case, and in fact probably isn’t the case for the vast majority of functions that fire on a UI event.
>> In Windows Forms, it’s possible to create the message pump on the “wrong” thread, have controls attached to that thread, and for the thread to exit. I can’t do that in Swing. I can’t do that in WPF. But I can do it in Windows Forms, because Windows Forms totally fails to hide the mess that is Win32 from me.
The original article I commented on wasn’t about Windows Forms vs. WPF, and again, if it had been, there largely wouldn’t have been anything to disagree with. Windows Forms != .Net.
>> Then I guess you create lots of applications that lock up every time the user tries to do something that takes more than a split second to complete.
As I said above, if the user can’t do anything meaningful while a function is executing then jumping through the hoops to make the UI remain responsive is a poor investment in time and effort, as the original article explicitly acknowleged.
>> Because it shouldn’t even be there. If you have an API that literally no-one on earth should be using, you should remove it.
You have a philosophical issue, not a technical one. As I said in my original comments, I’ll give MS the benefit of the doubt on backwards compatiiblity, since they A) have to deal with it at a level no other company even approaches; and B) have done a damn good job of it so far.
>> Right, except XAML and WPF both produce UIs that are wholly non-standard, unlike WinForms, which is only partially non-standard.
Which standard are we referring to?
>> Or perhaps you want hardware acceleration on Windows XP (Swing can manage it, Win32 can manage it, but WPF? Nuh uh; you only get acceleration of that on Vista. Even though Sun has managed to get both OpenGL and Direct3D Swing acceleration on XP…)
Again, the implementation of the graphics layers on Windows has many shortcomings, none of which has anything to do with .Net, and none of which combine to make Windows a “miserable” platform for development. It ought to be self-evident that complex and very functional UIs are successfully implemented in Windows all the time, as are direct 3D accelerated games and visualization apps. Had the author of the Ars piece produced a technical treatise on some of these shortcomings rather than an anti-Windows polemic there would have been no need of a response.
>>>>>Thanks for dropping by, DrPizza. I don’t think I said that Apple did nothing to NextSTEP, but rather that Next and XP were not coincident in time. I think everyone knows it took Microsoft longer to get from XP to Vista than it should have, and I wouldn’t argue that point. I just don’t think Apple’s acquisition of Next provides any kind of reasonable counterexample.
I never held them up as being coincident. I was saying that it was through the purchase of NeXT that Apple gained a fairly solid OS with a fairly well-constructed development platform.
Although it’s true that NeXTstep is old, it was also pretty forward thinking. It was always designed for high-end machines, which afforded it the ability to depend on powerful abstractions at the expense of somewhat inferior runtime performance (rather than the small and efficient low-level mechanisms of Win16), Back in the day, this meant that NeXT cubes and slabs were prohibitively expensive, which led to the ultimate failure of NeXT as a platform, but *now*, in the 21st century, the story is rather different. Hardware is abundant. We can pay the price of higher-level (and more flexible) abstractions. Today, a much higher price is paid by having to deal with something that’s too low-level. Win16 was parsimonious, and Win32 inherited a great deal of that. It made sense given the context of the small, cheap machines that Win16 was designed for, but it’s not a good parameter to optimize for today.
No, the thing that was (more or less) coincident with XP was OS X, and it’s this which has seen considerable (rapid) development. I think Apple has done much more with OS X in the timeframe of XP to Vista (10.1 to 10.4, almost 10.5) than MS did. Apple had–relatively speaking–a clean slate to start with, and this has given them much greater flexibility.
>>>>>Well, actually, I wasn’t saying that either. The point is that .Net is no more “dumbed down” than any other framework that aims to subsume the complexity of low-level APIs in higher level abstractions, and in fact .Net is much less dumbed-down than Java in my opinion. Some of the things the article complained about really represent handles that are there for experienced developers to use, that allow lower level concepts to peek through… such as the HWND properties that were complained about elsewhere.
I think Java provides primitives that are both more capable and better abstracted; that is why I cannot agree that it is just as dumbed down. Java does Collections better, but that’s far from the only thing.
>>>>>I don’t disagree with the specifics of the shortcomings in the collection classes that were cited. They would have made better examples for the original article than some of what was presented, nevertheless they don’t come anywhere near making Windows a “miserable” platform for development. If the article’s initial premise hadn’t been so over the top and silly no response would have been necessary. Had it been titled “Shortcomings in .Net” I doubt anyone would have noticed.
The problem is trying to strike a balance between the different readers I have. I know (from the responses I have received) that a laundry list of detailed complaints about .NET would have been great for some readers, but awful for others. I (personally) don’t think it was really necessary to do. Although Ars is a technical website and it’s a reasonably technical piece, I’m not going to apologize for being a bit hand-wavy when describing things like the unnecessary threading complexity of Windows Forms. That stuff is going to be reserved for the Ars forums.
The other problem with talking about the Collections is that I’ve bitched and moaned about their inadequacies so often that the entire subject bores me. It’s so thoroughly disappointing. Yes, yes, .NET proponents like to point out that .NET is much newer than C++ or Java. But that means it should be *better*, not worse. I could understand it making some mis-steps in the areas where it does something new and unusual, but Collections? Come on! We have Java; we have the STL. They both provide decent models for a collection library (I strongly prefer the STL, but Java is serviceable). There’s really no excuse at all for .NET being as bad as it is, except perhaps for NIH syndrome.
>>>>>Sure they are, but they aren’t necessary for 99% of Windows Forms programming. I don’t understand the obsession with the fact that the underlying system peeks out of the API in places. It’s only relevant to people who need to get at that stuff to solve a problem, and then it would be considered a strength that you can solve the problem at all.
If that were so I wouldn’t mind, but it’s actually *not true*. If your message pump gets created on the wrong thread–and it can do–then you can be in for a world of pain. It totally shouldn’t be an issue, but it can be, hence articles such as http://msdn.microsoft.com/en-us/library/3s8xdz5c.aspx to describe how to handle it properly.
>>>>>Blocking the UI to perform computation isn’t anywhere near always terrible, and it’s that kind of blanket generalization from context-specific personal experience that got the original Ars Technica piece in trouble. Unblocking the UI while computation is performed is only valuable if the user can do something else worthwhile in the meantime. This isn’t always the case, and in fact probably isn’t the case for the vast majority of functions that fire on a UI event.
It is always terrible. It stops me from resizing/moving/minimzing the window (at least until Windows realizes that it’s hung), if I’m using XP it hall-of-mirrors (because it can’t draw itself any more), and on Vista it’ll eventually grey out (again, once Windows has realized that it’s hung). Blocking the message pump for more than a split second is just *bad*. If you want to hourglass and not respond to buttons, that’s fine. But blocking the message pump completely is not defensible, because it stops the window from redrawing.
>>>>>The original article I commented on wasn’t about Windows Forms vs. WPF, and again, if it had been, there largely wouldn’t have been anything to disagree with. Windows Forms != .Net.
The failure to hide details that ought to be hidden is a recurring theme. For example, the FileStream class has a “Handle” member that lets you access the Win32 HANDLE that backs a file. Now that *obviously* doesn’t belong there. This is clear even from the BCL itself; there’s at least one class in the BCL that extends FileStream but which has no corresponding HANDLE. It has no choice but to throw an exception when you attempt to access the Handle property.
What does this mean? Well, it means you can’t blindly program against the FileStream object and have your program work for any subtype of FileStream. That kind of thing totally undermines the point of all this “OO” stuff. The thing is, IsolatedStorageFileStream probably *should* be a subtype of FileStream (at the moment it isn’t, because it’s not properly substitutable) but the failure to properly abstract implementation details means it isn’t.
IMO this happens time and time again with .NET. Sockets expose whether they use Overlapped I/O for some unfathomable reason. The Crypto library is totally constrained by the design of CryptoAPI, meaning it has various functionality deficits that Java Cryptography Extensions don’t have. There’s the already described weakness of ADO.NET to hide the specific details of different implementations.
This failure to provide clean abstractions is both frustrating for me (I want something *better* than CryptoAPI, not just a C# version of it) and problematic for MS. Because .NET is *so* tied to the Win32 way of doing things, MS has just built themselves a giant great big Win32 dependency. They have *yet more* code tied to the Win32 world. Contrast this with Java, which can withstand significant alterations in the underlying OS without altering the correct operation of Java programs.
The reason I think this is a problem is that I would like to see MS move to–let’s say–the use of virtualization to provide legacy support. I mean, we already hear rumours that this is what they’ll do anyway, and I’d like it to come to fruition. But you can only do that when you make sure that your *new* software isn’t “legacy”. I was really hoping, when .NET was new, that it would provide a clean break so that they could move away from the cruft that had built up. But because so much of that cruft shines on through, I don’t think MS has the ability to replace .NET’s underpinnings without breaking things.
>>>>>As I said above, if the user can’t do anything meaningful while a function is executing then jumping through the hoops to make the UI remain responsive is a poor investment in time and effort, as the original article explicitly acknowleged.
I don’t think so; locked up applications are really awful, because they prevent you from even moving the window.
>>>>> You have a philosophical issue, not a technical one. As I said in my original comments, I’ll give MS the benefit of the doubt on backwards compatiiblity, since they A) have to deal with it at a level no other company even approaches; and B) have done a damn good job of it so far.
The irony here is, that’s not actually true. There’s a particularly notable company that far surpasses what MS has done, both in terms of the extent of their legacy, and the level of support they provide. IBM’s support for legacy mainframe software is incredible, and streets ahead of Windows’ backwards compatibility.
One of the big issues with Windows is that basically MS has never got round to versioning their code. This means that when they change (say) user32 or GDI, they have to make sure that all the old programs work using the new codepath. MS doesn’t have the ability to say “Old programs use the old codepath, new ones use the new codepath (and get new features as a consequence)”. The result of this is that when MS changes a library, they often (accidentally) break something that an old program depended on. This is why there are so many shims in the Application Compatibility Toolkit; to try to undo some of that harm. But nonetheless, programs do break. If MS could freeze their old libraries, I think it would both improve their backwards compatibility (it wouldn’t eliminate changes to the old codepaths, but it would reduce them) and increase their ability to create good clean modern APIs.
>>>>>Which standard are we referring to?
Using standard Windows UI devices.
>>>>> Again, the implementation of the graphics layers on Windows has many shortcomings, none of which has anything to do with .Net, and none of which combine to make Windows a “miserable” platform for development. It ought to be self-evident that complex and very functional UIs are successfully implemented in Windows all the time, as are direct 3D accelerated games and visualization apps. Had the author of the Ars piece produced a technical treatise on some of these shortcomings rather than an anti-Windows polemic there would have been no need of a response.
The thing about games is that their UIs are rarely consistent with the rest of the platform.
But anyway.
The point is this:
Win32 is miserable because it’s full of decisions made with Win16. It’s also inconsistent, full of duplication, clumsy, inextensible, inflexible, etc. etc..
Win64 is miserable because it’s Win32 all but unaltered.
.NET is immensely disappointing because:
a) it contains poor abstractions, making it inconsistent, clumsy, inextensible, and inflexible
b) it mirrors Win32 in much of its design
c) MS is not committed to it. Major pieces of new Windows functionality are pretty much off-limits to the .NET world. If .NET is the way to be developing Windows apps, MS needs to make sure we can do whatever we want from .NET. We cannot. The strategy is so muddled it beggars belief.
Peter (I assume that’s who you are, although you haven’t identified yourself other than obliquely), are you seriously comparing IBM’s world with Microsoft’s? I think you’re being highly academic in general, but that one’s a real stretch. IBM produced mainframe software to run for a few tens of thousands of clients using hardware they completely controlled, in a software environment they completely controlled. Microsoft has been managing a desktop operating system that has evolved in a completely open hardware and software environment, over twenty-plus years and more than 100 million installations. IBM and Apple would have been a more reasonable comparison.
>> It is always terrible. It stops me from resizing/moving/minimzing the window (at least until Windows realizes that it’s hung), if I’m using XP it hall-of-mirrors (because it can’t draw itself any more), and on Vista it’ll eventually grey out (again, once Windows has realized that it’s hung). Blocking the message pump for more than a split second is just *bad*. If you want to hourglass and not respond to buttons, that’s fine. But blocking the message pump completely is not defensible, because it stops the window from redrawing.
It stops your application from repainting the window. It doesn’t stop Explorer from moving the window around (including dragging a snapshot of the contents along), resizing, or minimizing. Of course many apps running a task like that have popped a modal progress dialog anyway. Again, you’re right, for a subset of applications that need to do background tasks that take a lot of thread time it makes sense to spawn a worker thread as described in the Microsoft KB article. However, as you said yourself in the original piece most GUI applications don’t need this behavior, and for those that don’t the complexity of a multi-threaded UI is not a good tradeoff. For those that do need it the available mechanisms work fine. They’re too complex, and contain too many gotchas, but they work.
>> The failure to hide details that ought to be hidden is a recurring theme. For example, the FileStream class has a “Handle” member that lets you access the Win32 HANDLE that backs a file. Now that *obviously* doesn’t belong there.
It lets you access the handle. It does not require you to access the handle. If you do access the handle then presumably you’re doing so in order to accomplish something that you can’t otherwise do. Of course 99% of all the applications that need to work with files do fine with the standard API. The 1% that need to do something out of the ordinary aren’t going to blindly access the handle property on any old instance of the class. Is this good OO design? Of course not. But then if we insist on pure object-oriented bliss in our operating system APIs which operating system would we be allowed to use?
>> One of the big issues with Windows is that basically MS has never got round to versioning their code. This means that when they change (say) user32 or GDI, they have to make sure that all the old programs work using the new codepath. MS doesn’t have the ability to say “Old programs use the old codepath, new ones use the new codepath (and get new features as a consequence)”.
In my opinion this is a simplistic and idealistic history. None of the versions of Windows were free to be created in a vacuum, and there are still large corporate clients out there today that have Windows 98 clients (I worked for one less than a year ago). There are still OEMs creating software that has to run on some of these old clients. .Net contains more versioning controls, and no doubt this will continue to improve.
The whole debate is really pretty silly, imo. Does Windows suck for developers? Oh yeah, in lots of ways. But it doesn’t suck anywhere near as much as 16-bit Windows did, or as much as Win32 did. Having a managed code class framework to program to the operating system API is a tremendous advantage for people trying to create robust applications. Large portions of it are less than perfect, and that’s less than surprising, but almost nobody whose job it is to program Windows applications has the choice to up and move to Mac tomorrow. If they did then they would be bitching about that operating system three months later.
You wrote a piece that was intended to be inflammatory, and it got what I’m sure was the expected reaction. Probably the most flame-worthy part of it was your categorization of programmers in the beginning and throughout. I do appreciate you paying attention to what I wrote on this unknown blog of mine, and I don’t mean anything personal, but I believe you have a very elitist view. The points you raise are all interesting, and some are very valid. In an academic setting they would make worthy topics, but none of it makes Windows a miserable platform for developers. If it did, then developers would have abandoned Windows ten years ago, because it was a lot more miserable then.
Again, thanks for stopping by, and in as much as you are a guest, the last word is yours :).