Slashdot Mirror


The Code Is The Design

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."

9 of 354 comments (clear)

  1. Six Laws of the New Software by fembots · · Score: 4, Interesting

    Might be timely to revisit
    Six Laws of the New Software

  2. The Falacy of self-documenting code. by Ungrounded+Lightning · · Score: 4, Interesting

    But there's no substitute for writing the requirements, feature definitions, scopes and dependencies first, then the comments in the code blocks, then the code, and tar'ing those docs with the source code. The initial hump is steeper, but the total area under the work curve, over the product lifecycle, is much less.

    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.

    --
    Bantam Dominique roosters crow a four-note song. Once you've heard it as "Happy BIRTHday" you can't NOT hear it that way
    1. Re:The Falacy of self-documenting code. by Ungrounded+Lightning · · Score: 3, Interesting

      I agree with parts of your argument but disagree with others.

      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

      --
      Bantam Dominique roosters crow a four-note song. Once you've heard it as "Happy BIRTHday" you can't NOT hear it that way
  3. Yes, I read tfa by chris_mahan · · Score: 4, Interesting

    The idea is that great code resembles a picasso more than a f-16 fighter.

    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.

    --

    "Piter, too, is dead."

  4. Re:I'll Add... by chris_mahan · · Score: 3, Interesting

    It's like english. You know, the annotated book because the author really went all out and the reader has no fucking clue:

    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.

    --

    "Piter, too, is dead."

  5. Re:I'll Add... by DunbarTheInept · · Score: 4, Interesting

    In general, when I'm using a language with embedded documentation features (like Java's javadoc, or "doc++" that does exactly the same thing for C++ comments), I prefer to write the specs using the embedded doc tool itself (write out the spec for a java class by writing out the methods as do-nothing stub routines and then describe what they will do by prepending a javadoc comment to them - then when you generate your javadocs, you have the spec - and since they render into HTML, you can actually make the specs with a lot of complex formatting and all that, just the way the bosses like it. Thus my spec is also the skeleton of the code to be filled in. This approach works better, I think, because it makes it easier to keep the spec up to date when you discover a problem during the coding phase that requires a spec change.

    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.

    --

    Don't label something "offtopic" unless you know the topic well enough to tell what's on topic.

  6. read the damn article by Anonymous Coward · · Score: 5, Interesting

    man did anyone actually read the damn article?

    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.

  7. The Microsoft Solution Framework by PepeGSay · · Score: 4, Interesting

    Upon reading this again... I realize that the Micrsoft Solution Framework really gets at this idea very well, while still being applicable to large projects. It also attempts to protect against "releasing demo code". It heavily advocates early and continuous builds with an ever expanding capability, so that the development is always *technically* at a releasable stage (within reason).

    Flame away for mentioning MS in a good light.

  8. Re:False Economy by iabervon · · Score: 3, Interesting

    But there's no substitute for writing the requirements, feature definitions, scopes and dependencies first, then the comments in the code blocks, then the code, and tar'ing those docs with the source code.

    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.