Linus on specifications. All I can say is – amen. The rest of the thread is amusing in a horrifying way, an Adaptec guy ranting and raving and Just Not Getting It. If this is any indication of Adaptec engineers… I know which storage vendor I will not be buying from.
How we do the SW is indeed up to us, but I want to step in on your first point.
Again.
A “spec” is close to useless. I have _never_ seen a spec that was both big enough to be useful _and_ accurate.
And I have seen _lots_ of total crap work that was based on specs. It’s _the_ single worst way to write software, because it by definition means that the software was written to match theory, not reality.
So there’s two MAJOR reasons to avoid specs:
– they’re dangerously wrong. Reality is different, and anybody who thinks specs matter over reality should get out of kernel programming NOW. When reality and specs clash, the spec has zero meaning. Zilch. Nada. None.
It’s like real science: if you have a theory that doesn’t match experiments, it doesn’t matter _how_ much you like that theory. It’s wrong. You can use it as an approximation, but you MUST keep in mind that it’s an approximation.
– specs have an inevitably tendency to try to introduce abstractions levels and wording and documentation policies that make sense for a written spec. Trying to implement actual code off the spec leads to the code looking and working like CRAP.
The classic example of this is the OSI network model protocols. Classic spec-design, which had absolutely _zero_ relevance for the real world. We still talk about the seven layers model, because it’s a convenient model for _discussion_, but that has absolutely zero to do with any real-life software engineering. In other words, it’s a way to _talk_ about things, not to implement them.
And that’s important. Specs are a basis for _talking_about_ things. But they are _not_ a basis for implementing software.
So please don’t bother talking about specs. Real standards grow up _despite_ specs, not thanks to them.
Linus
The only problem with the no-spec approach is that it often leaves testers in the dark.
For example, if you don’t have a spec that says “the customer should be able to enter a threshold with accuracy of microseconds”, the QA person who discovers he can only enter integers as thresholds will not know he is staring at a huge bug.
I believe bugs are actually defined as “the program behaves differently than what the spec says”.
Unless “spec” means something completely different in the context of kernels and I totally missed the point.
Comment by shapirac — September 30, 2005 @ 6:33 AM |
Reminds me of something that I read somewhere, that when specifying a new software to be developed, the test plan and expected results should be developed together with the specs.
It appears that the best specs are the test plans with expected results.
Comment by tddpirate — September 30, 2005 @ 7:03 AM |
The problem comes when the bug’s in hardware. If you know that this device has a bug, then what? A kernel developer can embark on a grandstanding act, where he abides strictly by the moral principle of coding by specification and demanding that the manufacturer fix the bug. But in the meantime, it’s the users who lose, because they can’t use the device on Linux. (Unless the users have as much clout as the QA guy in that hardware company…)
— bi (http://mncw.tk/)
Comment by Anonymous — September 30, 2005 @ 9:14 AM |
I that case, I agree.
Comment by shapirac — September 30, 2005 @ 10:50 AM
Test plans and expected results cover whole systems
When you have to accomplish a goal by an integrated hardware+software system, in which the software has to work around a bug in hardware, your test plan and expected results cover, in principle, the entire system, not each component separately.
You, the ultimate user, do not need to know the details of the interface between hardware and its software driver module. You do need to know those details when you act as the hardware and/or software developer. However, in this case, there is some room for negotiations between the hardware and software people. In the case of buggy hardware, the room for negotiations is very small but exists – the hardware manufacturer will (sometimes)[rarely]{if they feel like this}<if they want to push more hardware> fix the bug in the next version or the next model or next year.
Comment by tddpirate — September 30, 2005 @ 1:08 PM
I slightly disagree
The specs are very useful whenever your program needs to interact with another. It’s even more crucial when your program needs to interact as a drop-in replacement for another. A very good example is a driver.
If I’m writing a driver for anything, I can say “these specs are unrealistic” all I want. It matters naught. Bottom line is, if I don’t write up to specs, anyone expecting a NDIS/ODBC/OpenGL/whatever driver will simply not work.
And when my OpenGL specs says I need to do something a certain way, and that’s unrealistic, breaking away from the specs is the WORST thing I can do. To put another way, a driver specs that is not being completely followed is taking worst combination of all worlds.
Shachar Shemesh
Comment by Anonymous — October 1, 2005 @ 8:53 AM |
Re: I slightly disagree
I have to ask… how many drivers have you written? the hardware specs are *never* quite accurate. You need to follow the spec, sure… until it breaks. Then you need to use common sense. Following the spec to the letter is guaranteed to end up with a non-functional and *ugly* driver.
Also, when you’re writing a driver for Linux, unlike a host of other operating systems, you’re at liberty to modify the OS to fit your driver better. There is no “spec” worth mentioning for the OSdriver interaction, just a set of best practices. Writing a driver “the way the spec says I should” is also guaranteed to end up with a driver that does not fit Linux. Partly, that’s what the original discussion is all about.
Comment by mulix — October 1, 2005 @ 1:59 PM |
Re: I slightly disagree
I’ll answer your mildly dismissive question.
I have written no hardware drivers for Linux. Guess what? These are not the only kind of drivers that exist in the world.
I have written other kinds of drivers, probably most complicated of which is PgOleDb, which is an OLE DB database driver for Postgresql. Believe me, there is more than one place along the way that I wished the specs were different. Much good that will do me.
The whole idea behind a spec is that software written to use an OLE DB need not know which driver it is using. It makes for excellent case when you have to write the driver in order to integrate support for a new database into an existing application. Some changes are still going to be needed, but nothing even remotely like what would have been necessary had the specs not been written.
As for changing the interfaces. Well, I thought we were going to be practical, weren’t we? I know you don’t believe that anything written for the Linux kernel should be out of tree, but the simple truth of the matter is that there ARE out of tree implementations of drivers. Some of them are closed source, and you will say “screw them” (I know, because you and I had this discussion in the past). Some are open source, but not released for a variety of reasons.
Even if they are all in-tree, however, changing each and every last of them just because you want to change the interface mid-development seems a costly endeavor. It’s better if whoever defined the interface did the job correctly in the first place, writing an interface that was based on reality rather than theory.
Anticipating your next question, yes, an interface must be defined by a spec. Otherwise you get people saying “what’s wrong with HTML’s de-facto standard of ‘it works on IE'”. An undocumented standard is not a standard. An interface that is not a standard is not reliable enough for anyone to aim at.
Shachar
Comment by Anonymous — October 2, 2005 @ 1:19 PM
Re: I slightly disagree
I’ll just clarify my previous point a little.
When you write a driver, you are writing an interface layer between the layer below you (be it database, hardware, Photoshop etc.) and the interface above you (NDIS, OLE DB, etc.).
What you do with the interface below you is your own business. If there are good specs (and there really almost never are), use them. If not, do whatever you have to do to get the system working. When working on PgOleDb, I certainly had to open up the PostgreSQL source code to check how a date was represented in its binary interface. Sometimes things are really hairy. For example, a certain data type is represented in Postgres as either float OR long-long, depending on the platform on which the *server* was compiled. Starting from 8.0, the client can query the server to find out which one it is. Before that you just had to guess. When that’s the case, my driver did what everyone else did – best effort.
However, when you write a driver, there is a more important aspect to your job. This is the upper interface of the driver. There, a spec is a must. Few spoiled people have the luxury of writing a driver that is only ever going to be used by one program. For everyone else, if there is no documented specifications regarding how my driver’s upper interface should look like, there is nothing for me to work with.
And it is there that whoever wrote the spec had better do his/her job right. If a database spec leaves me no choice but to copy the data back and forth several times during a query, performance is going to get hurt. The better designed the interface, the better the drivers written for it are going to be.
And a spec is a must.
Shachar
Comment by Anonymous — October 2, 2005 @ 1:28 PM