Please create an account to participate in the Slashdot moderation system

 



Forgot your password?
typodupeerror
×
Programming IT Technology

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."
This discussion has been archived. No new comments can be posted.

The Code Is The Design

Comments Filter:
  • by fembots ( 753724 ) on Tuesday March 01, 2005 @06:41PM (#11817505) Homepage
    Might be timely to revisit
    Six Laws of the New Software [slashdot.org]
  • Re:A nice quote (Score:3, Interesting)

    by KiltedKnight ( 171132 ) on Tuesday March 01, 2005 @06:54PM (#11817659) Homepage Journal
    That's what your whiteboard is for.

    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)

    by Ann Coulter ( 614889 ) on Tuesday March 01, 2005 @07:00PM (#11817735)
    Add to this the fact that comments are never compiled and you can say that comments can be anything related to the executed instructions besides the instructions themselves. That being said, it is very important to let developers (yourself, coworkers, and future developers) of the code have the ideas you had when you were writing the original code in the first place.

    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)

    by jwegy ( 775655 ) on Tuesday March 01, 2005 @07:04PM (#11817763)
    Design importance has a direct relationship to the size/complexity of the system being designed AND the "system" that is designing the system. By that I mean, design is a loose term. Me and my roomate can design better by talking about a general idea, and then sitting down and writing code while making adjustments where needed. This process wouldn't work in most coroporate cube farms where you have varying levels of skill, vision, ability to learn, types of users, and the all knowing PHB. This is a stereotype. I picture them developing a strict design that has to be followed. What is important, no matter what type of design you have in front of you is FLEXIBILITY. That designs needs to be able to change without throwing the whole system off balance. In fact, design should be a process which includes the implementation of itself.
  • by Ungrounded Lightning ( 62228 ) on Tuesday March 01, 2005 @07:11PM (#11817832) Journal
    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.
  • Dangerous.... (Score:2, Interesting)

    by Anonymous Coward on Tuesday March 01, 2005 @07:11PM (#11817835)
    While it may be true that designing is the most critical part of coding, it's dangerous to equate the code and the design. Because that implies, obviously, that writing code is the same as designing it, so just skip any forethought about design concerns and launch right into the coding.

    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.

  • by nate nice ( 672391 ) on Tuesday March 01, 2005 @07:14PM (#11817862) Journal
    "(there should be a compiler warning for them).

    (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)

    by chris_mahan ( 256577 ) <chris.mahan@gmail.com> on Tuesday March 01, 2005 @07:14PM (#11817864) Homepage
    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.

  • by kkoning ( 29512 ) on Tuesday March 01, 2005 @07:28PM (#11818010) Homepage
    Ultimately, I'd agree that "code is design", but that this is an overly simplified view. Looking at "x = y + z" and knowing an addition operation is being performed is one thng, but what do these symbols stand for? Why is the operation being done? How does this fit into the overall function of the software? These questions start to become more difficult and time consuming for a human being to answer without an overall design as a project increases in size and complexity.

    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)

    by chris_mahan ( 256577 ) <chris.mahan@gmail.com> on Tuesday March 01, 2005 @07:32PM (#11818042) Homepage
    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.

  • Re:I'll Add... (Score:5, Interesting)

    by DunbarTheInept ( 764 ) on Tuesday March 01, 2005 @07:34PM (#11818058) Homepage
    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.
  • by Anonymous Coward on Tuesday March 01, 2005 @07:48PM (#11818173)
    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.
  • by PepeGSay ( 847429 ) on Tuesday March 01, 2005 @08:02PM (#11818324)
    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.
  • Re:False Economy (Score:3, Interesting)

    by nagora ( 177841 ) on Tuesday March 01, 2005 @08:02PM (#11818336)
    I must have missed the memo that C++ had "failed".

    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)

    by Viking Coder ( 102287 ) on Tuesday March 01, 2005 @08:07PM (#11818399)
    Reminds me of Richard Feynman's Problem-Solving Algorithm:

    1) Write down the problem
    2) Think very hard
    3) Write down the solution
  • Re:False Economy (Score:4, Interesting)

    by iabervon ( 1971 ) on Tuesday March 01, 2005 @08:51PM (#11818946) Homepage Journal
    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.
  • by Ungrounded Lightning ( 62228 ) on Tuesday March 01, 2005 @09:47PM (#11819405) Journal
    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
  • Re:Oh Boy. (Score:1, Interesting)

    by Anonymous Coward on Tuesday March 01, 2005 @10:36PM (#11819806)
    The issue is not that "saying UML or flowcharts or whatever gets in your way" The issue is that the Big Design Up Front model is the wrong approach to development, and unusable. Most of the true design of a program does not come from requirements gathering, but during coding where the developer and customer come together and "try out" requirements. Therefore, it isn't until you have finished writing your code that you have a meaningful document of its design.

    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)

    by WGR ( 32993 ) on Tuesday March 01, 2005 @10:47PM (#11819898) Journal
    What is needed with UML is a way to execcute the design it creates. We need a tool that will parse the UML to generate the relationships between modules, show the data flow and transformations, allow one to make a mockup of forms and trace the consequences of the ranges of values allowed. If UML or any other design language is to be useful in the long term, it needs to be linkable directly to code. So every design change should be easily transferable from UML to code and there should never be the need to change code independently of the UML.

    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.

  • by cheekyboy ( 598084 ) on Tuesday March 01, 2005 @11:58PM (#11820422) Homepage Journal
    I can visualize lots of code/processes as UML type
    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 ,then perhaps it should be part of an IDE, when you hit NEW PROJECT. Do away with source files and include files and have the whole source in a database with each class in each 'file' or 'table', but do away with files as such, just make em transparent.

"Protozoa are small, and bacteria are small, but viruses are smaller than the both put together."

Working...