Jump to page content

Force and Encouragement

Caveats

Most if not all pages are just rough notes, and these pages as a whole are far from complete. More notes will be added in time, eventually, maybe.

If, from reading these notes, you conclude that I am off my rocker, you won’t be the first, and you may even be right. These pages may simply position me as an acolyte to the late Gene Ray.

No doubt there are a dozen and one reasons why none of this would ever work, but perhaps somewhere deep down there is a tiny fragment that could be used for something.

Chennese design

Raymond Chen is Microsoft’s Chief Apologist. Based on his writings, nothing is ever Microsoft’s fault. Or, if it was, they cannot be held to blame per the “water under the bridge” perspective: what’s done is done and there is nothing that can be done about it now. What we never get is a root cause analysis of Microsoft’s mistakes and a clear plan for how to not make them again, and again, and again. How for example did we get a shell language as horrible as The PowerShell-Haters Handbook? What was the point of the castrated Windows 11 taskbar when File Explorer in Windows 11 is just as unstable as it was in earlier versions of Windows. Why can’t Microsoft engineer a shell design and stick with it, instead of redesigning it over and over?

Chen does however make valid arguments about the poor quality of third-party development for Windows. Some blame must fall on Microsoft for their poor APIs and even worse documentation. Broadly, development under Windows is an all-round headache, with widespread failures both on Microsoft’s part and on the part of third-party developers. Most notable is the immense conceit and arrogance of third-party developers who deliberately avoid complying with any form of UI consistency. In some cases this comes down to the misguided belief that cross-platform development is viable, when in practice it seldom is. The whole user experience of a graphical system varies enormously between vendors and there is little practical way to bridge this with a single application. The end result is a fully custom UI that conforms no no expectations whatsoever. Being able to accept a Yes/No or OK dialog box with the keyboard (by pressing Enter, Y, N or Escape) often fails as the developers have never learnt how to use the keyboard properly.

For an example, see:

Why do I have to return this goofy value for WM_DEVICECHANGE?

“And they managed to get this to work in Windows 3.1 because they read the SDK carefully and found the five or six messages that require a nonzero return value and made sure to return that nonzero value. The rest got zero. And then when we added a new message that required a nonzero return value (which DefWindowProc provided), these programs continued to return zero and caused all device removal queries to fail.

So we had to change the “cancel” return value to something that wasn’t zero. To play it extra safe, we also made the “cancel” return value something other than 1, since we suspected that there would be lots of programs who were just returning TRUE to all messages and we didn’t want to have to rewrite the specification twice.”

Then:

Why are structure sizes checked strictly?

e.g.

“First, we found lots of programs which simply forgot to initialize the cbSize member altogether.

IMAGINARY img;
img.fDance = TRUE;
img.fSing = FALSE;
DoImaginaryThing(&img);

So they got stack garbage as their size.”

Thus one must consider, when designing a new operating system, not only how a system will behave when programmers are intelligent, co-operative, willing and careful, but also when they are idiots. This applies in particular to API calls and when generating and handling the event system messages.

These are all two-way situations.

Developers must be encouraged to produce good work by minimising pitfalls and avoiding unnecessary complexity in the design of the OS and its APIs and by providing clear and straightforward documentation to them. For example, consider avoiding using C and C++ and/or favouring a language where API calls do not require tedious and error-prone situations such as manually writing the size of a structure into itself. This breaks the “why get a dog and bark yourself” principle of computing: avoid human vigilance and let the computer figure this out. The computer knows how large a structure is: the programmer shouldn’t need to teach it. (This goes along with all the well-known and avoidable pitfalls such as traversing past the end of an array and overrunning buffers. Ensuring that all loops have an exit condition will be more interesting …)

The use of force is a necessary evil to be avoided where possible, as it will either discourage developers from the platform entirely, or lead to an arms race where stupid, egotistical and belligerent developers will apply greater force to ensure that they win.

Doing the right thing™ should be the most appealing choice, and where possible the most obvious, to minimise the amount of creative but abhorrent workarounds devised to counter the force with stronger force.

The system as a whole should nonetheless be designed to fail safe, by learning from known developer errors (of which Raymond Chen has catalogued a vast sum) and minimising the number of ways in which programmers are able to blunder. Chen has also covered forwards compatibility: where changes in Windows show up programmer errors that went unnoticed previously. Microsoft undertake, for commercial reasons, damage limitation by working around these bugs. In the open source world this is slightly different, as end users can identify and patch these bugs, but even open source operating systems require security updates, and being forced to remain on an out-of-date OS just to keep alive programs that don’t function on newer systems (and that the users have not the skills to repair) is not the situation that we want.