The Code Is The Design 354
danielread writes "In 1992 C++ Journal published an essay by Jack W. Reeves called 'What Is Software Design?' Many credit this essay as being the first published instance of assertions such as 'programming is not about building software; programming is about designing software' and 'it is cheaper and simpler to just build the design and test it than to do anything else'. developer.* Magazine has republished this groundbreaking essay, plus two previously unpublished essays, under the title Code as Design: Three Essays by Jack W. Reeves."
Six Laws of the New Software (Score:4, Interesting)
Six Laws of the New Software [slashdot.org]
Re:A nice quote (Score:3, Interesting)
I don't know how many times I've used a whiteboard to just diagram, erase, list, or whatever. Extremely useful tool, and when it's done, you have a picture you can translate into a design document.
Re:I'll Add... (Score:3, Interesting)
An extreme extension of your statement would be that the instructions for the machine have less gravity than the instructions for the developers of the program. I myself am of the school of thought that consider machine compiled code to be cheap, and expendable. What I consider to be most important are the ideas that lead to the construction of the machine compiled code.
These ideas should be very well developed, verified, and validated. Only after that will I begin implementing the ideas into instructions the machine can execute. It is my belief that as the program becomes more useful, it should also be less dependent on the platforms on which it was built for.
In summary, I believe that a piece of code should always include the original ideas about its purpose, function, requirements, and possibly history somewhere. To add to this, the developer should be able to easily extract this information.
Flex (Score:2, Interesting)
The Falacy of self-documenting code. (Score:5, Interesting)
Actually there is: Co-evolving the spec documents, comments, and code. Yes it helps a LOT to plan ahead - and it's a must if you want things to have a chance of getting done in any reasonable time. But trying to cast a spec into concrete in advance of coding is a false economy, too. The spec must remain maleable so the internal problems with it that are discovered during the coding phase can be corrected.
The thing there IS no substitute for is documentation separate from the code itself - whether it's a spec document, good comments, or (preferably) both. Self-documenting code is a falacy - because the code only documents what the code does, not what the code SHOULD do. (Grep is a great program. But it's REALLY broken if what you wanted was cat, or ftp.) Testing doesn't check that a program is "right" - only that it matches a spec. If you're trying to verify correctness of someone else's "self-documenting" code the only thing you can test is the complier. B-)
That applies to you trying to test your OWN code later. You are not the same person you were two months - or even two hours - after you wrote it.
Dangerous.... (Score:2, Interesting)
I will admit to being a project manager, not a developer. And I know that thinking through requirements and design specs is the "eat your vegetables" part of programming, and no one really enjoys it nearly as much as writing code. But I constantly see "code without design" being one the the easiest ways to get code that crashes, throws unidentifiable errors, won't handle valid input, or will produce invalid output.
Good design matters. Good coding matters. They go together, but they're not the same.
Re:ideally this would be true (Score:3, Interesting)
(not completely joking)"
I'd go a step further and throw a semantic error if suffeciant comment's were not found before certain constructs. Hell, make them part of the language. Or, at least provide an easier interface for programmers to document their code in a way similar to how many DVD's have the directories commentary attached...
Yes, I read tfa (Score:5, Interesting)
Picasso could not tell people how he did it, or rather people could not understand picasso's explanation.
An F-16 fighter, however, given enough years of schooling, could be explaned in great detail to anyone. This is why, although incredibly complex, there are thousands of F-16s out there. Yet there are only Picasso's picassos.
Likewise a great coder can't really explain how he wrote the great code. He just could. You can see the result, admire it, copy it even. But to apply the same "creative process" to a different problem, you'd have to be the original programmer.
I say this is why great programming is art and bad programming is not. Just like picasso is an artist and the guy who repainted the wall is not. It's because the "creative process" can't be passed on. It has to be self-invented.
Anything Shakespeare is Shakespeare. Nobody else can write Shakespeare, because they don't have the same creative process he did.
You can study Shakespeare, Picasso, Beethoven all your life and never be able to emulate them. Likewise a great coder's code can be copied, but the process that made the code can't be replicated.
Low Level vs. High Level (Score:2, Interesting)
For example, I might be able to look at an init script and, sans documentation, quickly understand what's going on to the point that I can understand and modify the script. It's hard to argue that I could use the same process for contributing a patch to say, PostgreSQL. I guess I'm trying to say that the relative efficency of people using different forms of design (either code, or explicit design documentation) is analagous to algorithmic complexity for programs.
Re:I'll Add... (Score:4, Interesting)
Ye whimsical faerie of yore
Whence came thee upon me?
Forlorn sit I stilled,
Prey to thy designs.
Now, the author wrote about his helplessness at dealing with his past.
Just because you can't understand what he said does not mean he should not have said it.
Perhaps it is the skill of the reader that must rise to match that of the author?
Perhaps it should be rewritten like this:
Memories from a hidden place make me sad?
Still too poetic, less descriptive?
How about: I am saddened by a memory.
You can make good code go bad by writing for the least common denominator in your organization (always the worst programmers)
Managers: You can raise code quality by letting go your bad coders. Not because they won't be writing bad code, but because the other coders will be able to write more powerful code.
Re:I'll Add... (Score:5, Interesting)
Alas, of late I've been dealing with stuff that doesn't have embedded comment docs and so I haven't been able to do that as much.
read the damn article (Score:5, Interesting)
He's not saying you don't do traditional software design work, or document. He's saying that if you compare the work that a software engineer does, it is equivlant to the design phase of normal engineering, not the manufacturing phase. That the program you deliver, is in essence, a completed "design" not a manufactured "product".
When you roll out and install this "design" in the target environment, this is the step which equates to normal manufacturing.
It's actually pretty insightful.
The Microsoft Solution Framework (Score:4, Interesting)
Flame away for mentioning MS in a good light.
Re:False Economy (Score:3, Interesting)
In the sense that it made no real difference. The programming world today is largely the way it is because of C, not C++. If C++ had never happened, but C, Smalltalk and Simula etc. still had happened, then I don't think there would be any noticable difference in modern programming style or technique, not even much difference in syntax. I think, anyway.
Obviously, C++ programmers might not agree!
TWW
Re:A nice quote (Score:3, Interesting)
1) Write down the problem
2) Think very hard
3) Write down the solution
Re:False Economy (Score:4, Interesting)
Those are the worst. You have the source, which seems to almost work. Then you've got the comments in the code, which are sort of relevant, but whenever the code gets sufficiently tricky that you'd have to read any of the comments, they're simply wrong. Then there are all the dependencies, which are incomplete and only include the obvious connections and not the ones which were added later. Finally, there are the requirements, which not only don't describe the actual program, but are simply impossible.
The best projects are ones where there's a bunch of code, which is written with names that suggest what things actually are and do, where everything is broken down into chunks which are sufficiently small to understand if you look at them, which has gotten arranged so that everything flows in accordance with the underlying problem being solved, and which is grouped logically, with related functions near each other within a file, in files, and in directories; and there is additional documentation, revised after the last change to anything it documents, which explains everything that isn't obvious from reading the code, as well as explaining where in the code to start reading.
The sole reason that code is the best documentation is that it is never incorrect. The program will definitely do what its source says it will. All other documentation must be held to the same standard, even though there is no automatic check for it. (One advantage of javadoc-style tools is that there are some automatic checks for accuracy; you can't have javadoc which gives the wrong name for a function). The worst thing is documentation which pretends to be authoritative, but which is out of date, and any document which predates the code is going to be out of date, unless the project is so trivial that someone with no experience could do it on the first try-- because that is what the original design documents are: the first try by people who do not yet have experience.
Personally, I think the best balance might be to start writing code with minimal planning (come up with the idea, divide the tasks, decree the coding style, arrange the process for adding tasks), but to have bitter and anal code reviews of everything that goes in. This requires the programmers to demonstrate that the code is clear enough to read and that the result including all additional documents is accurate and sufficient for someone who didn't write it to understand it based exclusively on the design.
Re:The Falacy of self-documenting code. (Score:4, Interesting)
Documentation that says what code should do merely moves the problem. Now you have to test the documentation.
That's one I disagree with. It's true on its face. But it misses the underlying point of documentation - whether comments or specs.
Having a separate representation to match against during a testing phase is actually a secondary benefit. The primary reason is to require the designers to create two, separate, expressions of the program's intent, in two languages / representation modes that are as distinct as practical.
Thinking in different languages (i.e. english prose vs. C++) gives them more opportunities to "view the bug hiding behind the blind spot from a different angle" and spot it. (If they're written by different people with different blind spots, so much the better.)
The idea is to have the CORRECT behavior documented in at least ONE of the representations. Then the testing process becomes one of finding the discrepancies, determining WHICH representation was right, and correcting the other.
This is surprisingly effective - even when both representations are written by the same person.
Documentation should be an abstraction of the code. It should describe at a higher level what is going on, so that an abstracted understanding can be achieved that is non-obvious by reading the code. This is merely to increase the efficiency of understanding unfamiliar software.
Again this is PART of its purpose - because educating the programmer is part of its purpose. Documentation can give explicit statements of structure that is only implied in the code. Documentation can explain emergent behaviors of assemblies that are non-obvious from the component pieces. Documentation can explain pitfalls which must be avoided - which are represented in the code only by their absense. And so on.
But documentation at a different level of abstraction also "shifts the view angle" and moves the blind spots - again helping to expose the hidden bugs by giving a "correct" representation when the code is incorrect. Documentation can also be redundant, giving more than one extra view.
IMHO the education of programmers is secondary - while the redundant, divergent, expressions of the same algorithm is key.
Testing will always have to be between code and end user expectation.
That I agree with.
Everything in between is fluff for testing.
And as you see above, that I disagree with. The things in between are useful tools to produce two desired effects:
- A desired behavior for the program, in the programmers' mind(s), which is reasonable, internally consistent, and well-vetted.
- A match between the programmers' idea of what the program should do and what it actually does.
The "design it twice in two ways" approach creates the latter two with high confidence. Then the only remaining issue is mismatch between the programmers' and end users' expectation. With bugs constrained to this narrow field they're generally few and quick to fix.
But programmers generally have little trouble understand a reasonable user's expectations when they actually sit down to think about it and write them out. The bulk of bugs come, not from user idea / programmer idea disconnect, but from programmer idea / code disconnect. Thinking of your documentation job as SOLELY addressing the first disconnect risks disaster.
= = = =
Interestingly, your logic DOES correctly state the reason "program proof of correctness" is also a falacy.
- Formal correctness proofs prove, not that the program is correct, but only that the program is consistent with a formal satatement of what is correct. (Again, "grep" might be perfect if you wanted a pattern matcher, but it's definitely broken if you wanted a web browser.)
- To be useable by a correctness proof (whether human or automated), what constitutes corr
Re:Oh Boy. (Score:1, Interesting)
This is the what is taught in Agile methodology : begin with a Story - a vague "essential use case" that only describe the goal, and does not involve specific implementation details. Rapidly progress from a set of nonfuctional towards functional proptotypes, and finalize the implementation details (such as which button goes where on the screen) This approach leads to a more satisfied customer. Otherwise, you wind up spending months (in some cases, years) perfectly a design that the customer find unusable - AKA the waterfall approach.
This article is not rapping software engineering. Most of the more progressive and experienced developers are swinging towards Agile over RUP (or have been for several years now). And you are right that the design document should propgate backwards - this functionality is actually being built into the more advanced UML tools.
Re:Oh Boy. (Score:2, Interesting)
This is difficult at the moment because our programming languages are still too low level. We are enamoured of language constructs that still are at the 1950's level of detail, such as worrying about word length in integers or buffer size for strings. Everybody learns C++ or Java etc. as first languages and from then on feel that they have to program at the level of these languages, only slightly higher than machine code. They force a programmer to break a high level view of the problems into tiny discrete chunks quite unrelated to the actual problem language.
Good compilers exist for functional languages that produce optimized code as fast as C++. Even modern Fortran has more functional programming abilities than C++. We need to see our data as a whole and program for the streams rather than the bits.
i think in uml therefore why draw it (Score:3, Interesting)
diagrams, but I see spending 4hrs drawing some crap as a waste when I could have completed the code by then.
I tend to write my code as nice as possible that even a drunk coder could understand it.
I may code up stuff fast with out UML diags, but if people/others need to maintain it, doing a high level UML or layout diag is easy enough to do on demand. Somethings are sometimes too easy to comprehend so id rather not waste hours doing fancy diagrams putting me to sleep.
Try imaging the UML diag for just IE, I bet theres a high level one, but not one down to each class/logic IF statement.
If UML is soooo important