Software Engineering Collected Wisdom

By Alan Silverstein; last update: Apr 9, 2026 -- Email me at ajs@frii.com.

UNFINISHED -- editing in progress -- HAH! maybe never

Contents:

Introduction
Software Productization
The Power of Vision
Contextual Inquiry
Automation
Human Factors / Gourmet Theory
Agile Programming
Payload Versus Scaffold
Documentation/Software Styles
Other Miscellaneous Philosophy
New material to merge (pending)


Introduction

What is this? This is one person's distillation of key learnings and advice about how to do software engineering better.

This webpage is the result of me spending over 30 years working as a professional software engineer. I developed and supported a wide range of commercial applications from boot loaders to business software, including along the way: System administration, install/update, symbolic debuggers, ASIC design and test tools, and a great deal of software process engineering.

I received a lot of professional training paid for by my employer. I also looked constantly for ways to improve my skills, although I'm not an "academic" who reads a lot of theoretical material. So what you have here is advice from a crusty old geezer who learned a lot about "where to tap with a hammer" even without always knowing the quantum physics behind the machinery.

This long but still brief webpage cannot replace a lifetime's experience in the field. But I still feel the urge to try articulating all in one place a summary of the best philosophies and methods I've incorporated. Many of the topics mentioned briefly here can lead you to finding much longer, and more precise, formulations of the same terms and concepts, if you're so inclined. "Take what you can use, and let the rest go by." -- Ken Kesey


Software Productization

Creating code can be easy or hard. Turning code into software by adding comments and other documentation is even harder. (Discussed in more detail in later sections.) "Productizing" software for long-term use and maintainability adds at least 2x the effort to just "ship a prototype."

Consider some major areas of possible investment effort:


The Power of Vision

Years ago I watched a series of videotapes called "the Power of Vision." I don't recall many of the details, but the author's name was Joel Barker, he's apparently still around (see here). The key points I took away were:

Suggestions for vision leaders:


Contextual Inquiry

This is a method for identifying and accurately understanding product and market opportunities. It can be done very formally, but its terms and concepts are valuable even when used informally. The key concepts are:

Suggestions for questions that should be answered and communicated early in a major new software design project:


Automation

People tend to think of "manual" versus "automated" methods as being polar opposites. But actually there's a relatively smooth spectrum between the first-time (prototypical) execution of any task, and the 100% mechanical (without human intervention) implementation of the same action.

For example, writing down a recipe (a real one, or steps to follow while interacting with a computer system) might be considered "10% automation." Using the recipe is still mostly manual, but not completely reinvented each time.

One of the arts of software engineering is recognizing and striving for the best balance between manual and automated methods. Humans are very good a heuristic reasoning, while computers are very good at rote repetition and rule-following. Humans drift off mentally and make errors of inattention blindness, while computers are so dumb they make errors of stupidity.

Software products can fail because they require too much detailed (or expert) attention from users, but also because they are overly complex and opaque, failing to instill a sense of end-user control and understanding. "Too clever is dumb." -- Ogden Nash

My suggestion is: Software product developers should consciously and routinely ask themselves what's being automated, how, and why; and what tasks end users care about, but are better off doing more-manually rather than ultimately with a negative ROI trying to over-automate.


Human Factors / Gourmet Theory


Agile Programming

Consider these homilies: "No battle plan survives contact with the enemy," and, "Plans are nothing, planning is everything."

If you try to spell out a UI, architectural plan, etc, in great detail before writing any code, you are probably wasting your time, and others' too if you subject them to design reviews. It's more important to have a well-articulated and shared higher-level understanding of the project's vision, goals, end user tasks, and tradeoffs. Then as code development and alpha testing proceeds, the team should remain flexible/"agile" about "refactoring" existing code and documents based on new understandings.

The ideal goal is to have documentation and code in hand at every moment that best matches the statement, "this is exactly what we would have created from the beginning, if we knew then what we know now."

Of course in real life there are schedules, milestones, and soft/hard freeze/delivery dates. In a healthy software project, everyone including the management understands that refactoring is necessary, a continual striving for perfection balanced by various tradeoffs. Discussions are more about what to go back and change, and how soon, than whose fault it is that something wasn't understood well earlier, and how fouled up it all is now.

Finding new product disconnects early, and fixing them, should be seen as a glorious path to success, rather than an unsettling lack of stability... Just so long as the spiral continues upwards.


Payload Versus Scaffold

I find it useful to consciously label deliverables as payload or scaffolding (umbilicals). The former are documents or code features intended to be of long-lasting value to downstream users, including, say, someone writing client code around your library. The latter are features known to be temporary throwaways, including slides created for a team meeting and obsolete after the fact.

Beware however: Quite often a scaffold or prototype is thrown into production for lack of a better solution to a downstream problem. This is an argument for doing professional-quality work on almost anything you touch. Also there's no excuse for shortchanging your "internal" colleagues with inferior documents or tools just because "we'll never ship this to a customer."


Documentation/Software Styles

I don't want to engage in any more long debates about style issues. I've been around that loop more times than I care to remember. It starts out fun, and it can be constructive or destructive, but is usually tiresome regardless.

But I do think it's important for everyone on a team to have an attitude of continual learning and improvement in their own skills and styles, sharing examples of best-practices, and being as egoless as possible.

That said, here are a few suggestions to consider:


Other Miscellaneous Philosophy

I find all of the following terms and concepts to be useful metaphors when working on software design and implementation. But I don't know how to categorize them further.


New material to merge (pending)

And yet more old material, from 1991-1998, to eventually merge above. Software with Style

SOFTWARE WITH STYLE

Good Ideas and Best Practices For Software Engineers

(Or, "Creating Mind-to-Mind Portable Software Without the Benefit of Telepathy")

By Alan Silverstein; email me at ajs@frii.com
Last update: 981210 (tweaks 260403!)

CONTENTS:

  1. Introduction
    1. What is This?
    2. Background and Goals

  2. General (But Relevant) Philosophy
    1. Concept of Context versus Content
    2. Information is Carried in Differences
    3. Concept of Attributes
    4. Productivity and Quality are Inseparable
    5. Seek Feedback and Objections from Others
    6. Human Sensory Model
    7. Miscellaneous Philosophy

  3. General Suggestions on Engineering Practices
    1. If it's Worth Doing, it's Worth Doing Well
    2. Recycling
    3. Paperless Engineering
    4. Managing Communications
    5. In English Text
    6. Miscellaneous Suggestions

  4. Tips on Interacting With a Computer
    1. Effective Use of Tools and Resources
    2. By Your Command

  5. Suggestions About Implementing Software
    1. Generalities
    2. Suggestions about Software Content
    3. Suggestions about Software Style
    4. Suggestions about User Interfaces

  6. Suggestions About Implementing Documentation


  1. INTRODUCTION

    1. What is This?

      What is this? It's a dessert topping and a floor wax, ...errr, It's a website and a seminar...

      So what's it about? This document offers you lots of ideas for how to write software (and documents) with style.

      "Style? What's that mean?" As a famous person once said, "We all have style, but few have class." (I forget who said this.) So maybe this sermon is really about writing classy software -- but "software with style" had a better ring to it. Also, while C++ has class(es), typical C++ programs deserve an F for style...

      Anyway, right about now you might be wondering, "where does Alan get off, preaching to me about software with style?" Let me address that (very reasonable) concern with lesson #1:

           Perfectionism != perfect.

      I wrote this document because I'm a perfectionist and I want to share it around. This in no way means I'm perfect, or even necessarily better than someone else at software engineering. It does mean that I try, and I care, and I wish most everyone else I work with would try harder and care more too.

      As another anonymous famous person once said: "Plans are nothing; planning is everything." Similarly, perfection is nothing, perfectionism is everything.

    2. Background and Goals

      This document is based on my years of experience as a software engineer. (I started at HP in 1977.) Much of the content is debatable, and much of it is "fuzzy", but all of it works for me and I find it relevant.

      Using concepts and practices such as I've set forth here, I've written a lot of pretty successful software, relatively quickly. OK OK, so most of it is obsolete today, but it had a low defect density while it survived, and people didn't hate using it or adopting it...

      Maybe if there's any truth in the words that follow, you could get the same results?

      Around 1991 I presented this seminar to eight UDL engineers in a bit over an hour and a half. Items that probably should be skipped for a shorter presentation are marked second-level.

      If this material has value to others, it is not as specific pragmas or practices, but as a set of models, concepts, ideas, ideals, and philosophies. Perhaps to be effectively conveyed it must be presented orally, with animation and examples? Or maybe it suffices if people just think (and debate) about the issue at all?

      Anyway, what follows are goals; no human being (including me) can live up to them all. So, in the immortal words of Ken Kesey, "take what you can use and let the rest go by."


  2. GENERAL (BUT RELEVANT) PHILOSOPHY

    1. Concept of Context versus Content

      • "There is no such thing as a context-free message." -- paraphrased from NLP
        "Only that in you which is me can hear what I'm saying." -- Ram Dass

        For any semantics (meaning) to be accurately conveyed between entities, they must have context in common. In software this context includes the computer language, the overall design and goals of the application, the technical rationale for the design, abbreviations and naming conventions, etc.

      • Tradeoffs between context and content. Choices between size (completeness) and context requirements (assumptions).

        Most writers assume too much context knowledge on the part of the reader, because in the process of creation they are deeply and intimately engrossed in the details. They "can't see the forest for the trees." Learning when to record your overview and assumptions in documents or comments, and how to make them digestible, is a fine art worth cultivating.

      • Example: Put a header (title, author, date, version, etc.) on every document and in every source file you expect will live longer than one day.

      • Example: If you do something unusual, proudly explain why.
        "Here a miracle occurs."
        "Use cc -w below to hide 17 warnings I think don't matter and I'm too lazy to fix."
        "If the pointer ends up null, which should never happen, ..."

      • Concept of "software rot" due to changes in context. Unavoidable, but predictable and manageable.

        Successful software survives long enough to rot and need maintenance, even if it's initially "perfect".

    2. Information is Carried in Differences

      • "Any difference that makes a difference is information." -- Gregory Bateson
        Corollary: Any difference that makes no difference is noise.

      • Formatting details and arcane inconsistencies might or might not carry information.

        1. Avoid confusing readers with style or other changes (for example, random use of color on a slide) which is confusing because it looks like a hidden message but isn't. For example, the formatting of this very paragraph is stupid.

    3. Concept of Attributes

      • Every object (real, software, or intangible) has many attributes -- of which some are more relevant than others.

      • Know Thy Attributes:

        • Consider the common, disjoint, significant, assumed, etc. attributes of any problem, package, etc.

        • Seek to define problems in terms of common and disjoint attributes, clearly labeled. (Useful analogy: A mathematical eigenvector.)

        • Focus on relevant attributes, and on separating them from the irrelevant ones (a personal weakness).

        • Example: The defining attributes of a product build are the release, integration cycle, product, flavor, and source tag. Examples: 11.01, 6, SAM, prodoff, sam11x. Fuzziness exists because flavor (such as debug or product) might also include the target OS release (such as $TRIREL = Roseville), which must also agree with the build environment release (11.01) (and IC cycle), and probably the source tag (sam11x).

    4. Productivity and Quality are Inseparable

      • Productivity = Effectiveness + Efficiency. (Do the right job; do the job right.)

      • Quality = FURPS: functionality, usability, reliability, performance, supportability (and other trivia added later).

      • second-level "Creativity is no substitute for knowing what you are doing."

      • second-level "A problem found by appraisal must be found and fixed each time it occurs. A problem found by solution is gone forever."

      • second-level "Don't confuse things that need action with those that take care of themselves." (DeMarco monkey theory...)

      • Approach every document or program as if you would have to own it forever (or until it's obsolete, anyway).

      • "It's a poor workman who blames his tools."

    5. Seek Feedback and Objections from Others

      • "The meaning of your communication is the response that you get." -- NLP

      • "Negative feedback is useful information." -- NLP

        When someone asks you a question, any question, about your code or document, consider it as useful feedback for how the work could be improved.

        (Of course some people are induhviduals and some questions are stupid. But at least consider whether the question represents a valid general case.)

      • Most human behavior is more easily externally-modified (via feedback from others) than internally-modified (via simple willpower).

        • Accept feedback as gracefully and usefully as you can.
        • Cheerfully "guide" others (but be diplomatic) (how am I doing so far?)
        • For best results, everyone needs everyone else's help.

    6. Human Sensory Model

      second-level

      • NLP (novo-linguini pragmatism, ...errr, neuro-linguistic programming) says the human senses are visual (V), auditory (A), kinesthetic (K), gustatory (G), and olefactory (O).

      • Mind as metaphor. People think in symbols that parallel their senses, chunking as they go.

      • Consciousness is, among other things, an internal metaphor based on sensory input, primarily V,A,K.

      • People think (analogize) sensorily (representational systems).

      • These NLP principles might be useful when coding or documenting. For example, a rich experience for the user requires multi-sensory input; appeal to primary channels (per individual); etc.

    7. Miscellaneous Philosophy

      • "For best results, authority and responsibility should be commensurate."

      • Risk = Probability + Seriousness.

        • Many (the most interesting) situations have low probability but high seriousness, or vice versa.
        • "Life is difficult because it is non-linear."

      • Be aware of distinctions and tradeoffs between manual and automated tasks:

        • A difference of degree, not of kind.

        • Initially conduct tasks manually, or at least model them manually, so you know them well before automating them.

        • Automate appropriate tasks, and only those tasks.

        • "Let the machine do the dirty work."

      • People live in a differential world. They focus on differences, which means meaningless differences (noise) are a challenge to ignore.

        Be consistent so the real purpose, message, or benefit shines through and is maximally useful.
        Be inconsistent when it shortens the overall size of the message! For example, "#endif /* FOO */" is brilliant when the "#if" is 10 lines back, but stupid and noisy when it's just one line back.

      • People are adept at intuitive pattern recognition and matching, even where none exists (order out of chaos).

        Offer them meaningful patterns that help fast, accurate comprehension.

      • People do whatever is easiest; the path of least resistance.

        To get them to do what you want, you must make the "right" path easiest to follow.

      • What's measured gets optimized, but costs can invisibly migrate to other, unmeasured places. (Tom DeMarco)

      • You can do anything you want, but not everything you want.

      • second-level Lack of capability is usually disguised by lack of interest.

      • second-level Information that is hard to access is worth less than none at all -- because it must be maintained.

      • "If you only have a hammer, you tend to see every problem as a nail." -- Maslow

      • "In success there's a tendency to keep on doing what you were doing." -- Alan Kay
        Also worth reading: "The Innovator's Dilemma" by Christiansen.


  3. GENERAL SUGGESTIONS ON ENGINEERING PRACTICES

    1. If it's Worth Doing, it's Worth Doing Well

      • (Well actually, "If a thing's worth doing, it is worth doing badly." -- G. K. Chesterton
        -- At least things that are done for fun; and work should be fun; but not at the expense of others who will rely on, adopt, or use your work. Professionalism = giving up some fun to produce a higher quality result.)

      • Almost everything survives longer than intended -- long enough to become a support burden, an intimate irritant.

      • If you haven't got time to do it right now, how will you have time to fix it later?

      • Acting like there will be no time tomorrow is a self-fulfilling prophecy.

      • Building software "right" in the first place is a winning strategy. Get and stay ahead of the power curve.

      • "The less time planning, the more time programming."

      • Take pride in your work... Really!

    2. Recycling

      second-level

      • 'Tis nobler to steal than to [re]create.

      • Recycling allows you to focus on higher-level productivity.

    3. Paperless Engineering

      second-level

      • Relying on paper is an albatross around your neck. It slows you down and puts you at the mercy of the printer.

      • Paperless engineering is a new, higher state of being which takes some work to reach, but can be (nearly) achieved.

      • Various specific tricks to help "going paperless":

        • Become aware of why you use paper. Each time you print something, ask yourself what question the paper will answer, and whether you really need paper to answer that question.

        • Become proficient in use of windows; editor (including marking and jumping); search commands like grep; overview commands like cscope.

        • When the urge arises to print something, ask yourself if it's an opportunity to practice going directly to the computer for the result you need. That is, "practice paperless."

        • Pay attention to the paper you produce. How did you use it? Did you really need it at all?

        • If you find it hard to look at a computer screen for long periods, is there anything you can change to make it more comfortable?

        • If you think it's easier to "get the big picture" by spreading out paper on your desk, what's stopping or limiting you from getting the big picture through your computer screen?

    4. Managing Communications

      • Common technical communication paths (in priority order): personal visit, telephone/voicemail, email, paper/whiteboard.

      • People are nice. People are friendly. We're all more or less tribal, and we love to interact. "Humans are communications junkies. We just can't get enough." -- Alan Kay

        But interrupts carry a very high price.

      • Be considerate of others as you would have them be considerate unto you.

        If it's not urgent and it doesn't require a lot of back-and-forth, put down that telephone and use email!

        If it's quick and/or you're in the mood to chat in person, stand quietly by the other person's desk until they are at a good interrupt point. Let them "push their stack," or even wave you off until later.

      • Give priority to personal visitors, then to phone calls, then to email. Generate your own interrupts accordingly.

    5. In English Text

      • Keep sentences and paragraphs short and easy to skim and digest.
        Like Hemingway. Clever. Though perhaps excessive.

      • Highlight highlights.

      • Be creative in your formatting.

      • Avoid an "army of ants running across the page." Chunk, layer, hierarchicalize your text for fast navigation and maximum retainability. (Note: The preacher is allowed to occasionally verb his nouns.)

    6. Miscellaneous Suggestions

      • Be aware of and use the "Teddy Bear Effect": Describe a problem to someone out loud, even if they just nod and smile. (A teddy bear just listens patiently while you think out loud.)

      • When marking changes to a printed document: Make circles near each change or comment, in the margin, to draw attention to them.

        • The eye is good at noticing round objects, like this: O
          Or even: ( )

        • Then you or someone else can find your markups later.

        • Also the recipient of the written comments can use the circles as a form of record keeping. Put a checkmark in the circle for "change made", X it out for "no change", write in a question mark for "not yet resolved", etc. This is a nifty technique.

      • Make your code and documentation easy to search with grep and friends. Realize that your text might be taken out of context one line at a time.

        For example, for a Log() call, try to put the message to be logged on the same physical line as "Log", so a "grep Log" yields useful results.

        (Unfortunately this often conflicts with readability in the context of the document. Well you can't have everything.)

      • Nothing happens without a charter and a champion. If you want it done, be sure someone owns it.

      • second-level Spell out defaults and assumptions.

      • second-level Be conscious of feature creep, and aware of how closely you are following designs and plans.


  4. TIPS ON INTERACTING WITH A COMPUTER

    1. Effective Use of Tools and Resources

      • Concept of "span of control":

        • Unconscious limiting beliefs -- you don't even try to do something because you intuitively know it's "too hard".

        • That is, the ROI is too low because the investment is too high.

        • What could you accomplish if only you were faster and more efficient with your tools?

      • Increase your span of control:

        • Ensure fluency and comfort with your tools and environment.

        • Consciously engage in "axe sharpening". (Automatic two points awarded if you're still reading this document.)

        • Learn from those around you and share useful tricks.

          When a co-worker asks a question, don't just give them a fish. If you can, teach them how to fish for themselves. They'll love you for it... Trust me.

        • Learn by doing; add as you go. Never stop learning. Trust that your brain will retain what you need and use.

        • Typing speed, editors, windows (softkeys, cut and paste), etc.

      • Synergistic effects; "serendipitous synergism".

      • Write tools to assist repeated operations (macro-ize).

    2. By Your Command

      • When giving a computer commands, formulate them mentally as questions you are asking, so it's clear to you what you are after as an answer.

      • Look for easier ways to accomplish tasks.
        "The lazy man is doomed to succeed." -- Robert Heinlein


  5. SUGGESTIONS ABOUT IMPLEMENTING SOFTWARE

    1. Generalities

      • Code = Algorithms + Data Structures. (We all know that.)

      • Software = Programs = Code + Comments!

      • Software and documents are messages:

        • People don't often realize that programs are multi-purpose messages. They are intended to be read by a compiler that is very nit-picky about syntax but couldn't care less about appearances. And they are also intended to be read by human beings who are best at reading natural languages.

          "Why didn't you put a comment header on this file?"
          "I thought it was obvious, and besides, it compiled and ran OK."
          "Well great! It compiled once, and it's obvious, so can I throw away your source file now?"

        • The real art of software is writing two intertwined and complementary messages, one to the compiler and one to the human reader, which will be maximally correct and understandable to both.

          Personal note: I hate software in which I must "play compiler" to infer the purpose or context of the algorithm.

        • The program itself (code or comments or both) is not necessarily the only useful representation of the problem and its solution. The code is enough for the compiler. The comments may be enough for some humans. However, in many cases, graphical, auditory, or other (redundant, alternate, abstract) representations help human readers to more quickly comprehend the essential abstractions. That's why structure diagrams and control and data flow diagrams have a useful place in the software world.

        • There's also a fine art to where you put your comments and documents, so they can be found when needed, without getting in the way when they are not.

          Perhaps in an ideal world we'd view everything through a browser, and every connection would be a hyperlink? (And everyone would be very good at writing web pages, too?)

      • Form is as important as content.

        When the code compiles and runs you are only half way done (or less).

      • Portability to other people's minds is more important than portability to other computers.
        "Computers talk to each other worse than their designers do."

      • Coding with style and class:

        • We all have style but few have class.

        • Strive to be a "classy" software author.

          (Yes, of course, one person's "class" is another person's nightmare. At least put energy into caring about it. Discuss it with your peers. Beat their irrational neural nets into conformance with your own...)

      • Be consistent, accurate, and concise in naming and referring to objects and concepts. Minimize chances of subtle miscommunication.

      • Document before coding:

        • This is more work to maintain but clarifies the goal nicely.
        • Helps find design flaws.
        • Establishes user perspective.
        • If you can't write it right, you can't think it right or program it right.
        • "Don't document the program; program the document."

      • Build templates for yourself to make coding quicker. (My personal template.c file is now 835 lines long.)

      • second-level Concept of redundancy versus orthogonality.

        Tradeoffs in clarity and ease of comprehension and maintenance.

      • second-level Iterative refinement, versions, stepwise completion and testing. Narrowing-in as a way to avoid doing the wrong job.

      • second-level Choose priorities carefully; for example, size, speed, flexibility, quality.

        Performance is easier to add than clarity.

    2. Suggestions about Software Content

      (Alan finally treads on the thin ice...)

      • What you call an object matters!

        Put energy into choosing appropriate object names.

      • Use ergonomic names and abbreviations for things, that is:

        • Psychologically distinct (must be balanced against the need for a pattern).

        • Descriptive.

        • Easy to deal with and remember; predictable; follow a pattern.

        • Not easily misinterpreted or confused.

        • Long enough to carry information, especially out of context such as via grep. (People who call a variable "t" or "tmp" should be strung up by a LAN cable.)

        • Short enough to be one psychological chunk, not a sentence all by itself. (Avoid "cdf_determine_update_path", it's a mouthful. Abbreviate appropriately.)

      • For software bundles large enough to expect some "learned context" on the part of the reader, consider rules that assist visual type checking. Examples:

        • All names begin with a type indicator, such as "i" for integer, "c" for character, "st" for structure, "un" for union.

        • All pointers start or end in one "p" for each level of indirection (except C strings have one less level because they are so ubiquitous).

        • Conventional names for concepts, such as "min", "max", "lim", "end", "first", "last", all built into variable names.

        • For example (note, little of my code is this rigorous, because little of it is part of a big enough package to deserve it):

          iSwapLimp pointer to integer which is the value of the limit (end + 1) of swap area
          unMapChar union that maps chars to something else
          stFSNodepp_t fileset node structure pointer pointer type: typedef struct FSNode ** stFSNodepp_t;
          CHNULL macro: #define CHNULL '\0'
          CHNULLP macro: #define CHNULLP ((char *) NULL)

      • Expect the reader to know the computer language; that's part of the context.

      • It's good to use language features to produce less and simpler code to digest. For example, use C trinaries in place of lengthy, redundant "if" statements.

        It's not necessary to explain every use of the language -- but do give general ideas of what's going on in tricky cases.

      • Parameterize mercilessly, for clarity. Don't literalize unless unavoidable or preferable.

        • For example, don't bury program names or dates in the file; they're part of the context. (Author and version are OK though, except perhaps leave out author when the file is stored in a software configuration management system.)

        • "Render unto context that which is contextually sensitive."
          "Will this look stupid when someone else views it out of context a year from now?"

      • second-level Write simple (possibly slow) code first, and only then work on enhancements and performance. (Think about enhancements and performance during design -- but make conscious tradeoffs.)

        "Make it right before you make it faster."

      • Every error message must be self-explanatory (with a reasonable but minimal context in the user's head) or clearly documented in a compendium of errors.

        • The elegant engineer treats every code branch, however rare, as if it were mainstream code, because when it executes, it is mainstream code.

        • "Never test for an error condition you don't know how to handle." -- Steinbach
          Some conditions are better left to the context. For example, sometimes the right thing to do is allow a core dump (kernel context) if context assumptions are violated.

      • Ensure your code "does nothing" gracefully.

      • Any program which reads a file of input commands or data that are human visible or editable should allow comments and blank lines in that data, preferably in a conventional form. This should be well-documented.

      • second-level Replace repetitive expressions by calls to a common function. Modularize!

    3. Suggestions about Software Style

      (The ice gets thinner...)

      • Past negative experiences with rigid, inflexible coding rules, or debates about them, drive people back to rampant individualism -- and anarchy.

        "Oh no, let's not get into that religious debate again."
        But, "believing themselves to be wise, they became fools." So let's briefly revisit the debate...

        • Avoid pendulum swings; seek balance.

        • Large projects demand guidelines and conventions, if not rules.
          (Rules are checked and have penalties...)

      • Compassionate coding: Empathize with the reader.

      • Code should look and read like prose or poetry, as much as possible, not like an army of ants running across a page.

        • Block code into chunks, with comments and indentation.
          (My personal template.c file illustrates this, though it's not a complete program, and no longer available on the website.)

        • Make your code easy to scan quickly to find "the right spot".

        • The single greatest failing of all programmers is to make the "big picture" clear during a quick skim.

          "Software macho": "It was clear to me, it should be clear to you. What's your problem?"

          Counter with: "If you don't document your work clearly enough, that's OK with me. You can be my living, breathing documention. I assume I can come visit you as often as I find necessary... ?"

      • Comments, whitespace, and newlines are cheap. Be generous with them.
        (I keep a bucket of whitespace at my desk... Help yourself any time!)

        It's not the quantity of comments that deters the more proficient programmer. It's where you place the comments in the code. Block them before a fragment of code and try to keep inline comments to the right of code. The more proficient reader can concentrate on the code and bypass the comments. The comments are still available, however, for the neophyte, or as a reference.

      • Less source code is better code.

        • Tightness is good, but make it ultra readable and well-commented too. Less to digest, but don't make it harder to read.

        • second-level Verbosity is not a virtue by itself; neither is terseness. It depends... On the context.

        • second-level "Everything should be made as simple as possible, but not simpler." -- Albert Einstein

      • Most programmers know English well (or at least it's the common language).

        • When in doubt, follow English-like syntax rules so the signal-to-noise ratio is highest.
          Why would you put space before punctuation marks , except maybe to align them vertically ?

        • Don't vary for ad-hoc reasons -- don't get "cute" -- keep your creativity at a higher level.

      • Avoid annoying, insulting, and irritating the reader (or the user, for that matter).

        "Who is this 'we' you keep referring to in your comments? I didn't write this trash, you did."

        Humor has little place in software. A cute joke or a clever object name tires quickly when the code is revisited.

        "Have you heard the self-referential joke about the guy who was giving a sermon... ?"

      • Keep a clean house; that is, remove declarations or code no longer used. They can drive people nuts.

        "Use the Force, Luke." If you have an SCM (software configuration management) system, like HMS or ClearCase, get obsolete files and text lines out of your current working set! Store them in past versions in the SCM, not in commented-out code.

    4. Suggestions about User Interfaces

      • Know Thy User.
      • Never Patronize Thy User.
      • Never Anthropomorphize the Machine.

        In particular, avoid "I", "please", etc. Machines should be neutral, not chatty, and not over-friendly.

      • second-level "A system meant for common use should rarely need uncommon knowledge." -- Redford

      • second-level "No one understands everything, and no one needs to." -- Redford

      • UNIX commands should produce usable usage messages when invoked with no arguments (if appropriate) or with the "-?" illegal option.

        • The summary should put non-optarg options first, then options with option arguments. (Also in the manual entry. Put the options summary in SYNOPSIS; not just "[options]".)

        • Follow with explanations of each option, including defaults!

        • Use getopt(3C)!

      • Every error message must contain the name of the emitting program, based on invocation name (not hardwired), unless emitted in an unambiguous context.


  6. SUGGESTIONS ABOUT IMPLEMENTING DOCUMENTATION


    OK, that's it, all of it. Well, sort of. If I had hours and hours to lecture, I could go off on zillions of virtual hyperlinks that start in the distilled wisdom (wisdumb?) above. Like for instance, my "Guidelines For Designing Administrable Computer Services" (no longer web available).

    Well anyway, thanks for listening. Maybe I'll run your code someday and think you're a genius. Maybe I'll have to read your source code, and I'll think you're a saint.

    More raw text later:

    ...I came around to appreciating, even at times extolling, most of the virtues of rapid design and refactoring (agile programming). It admits that "no battle plan survives contact with the enemy," that we aren't initially the experts we think we are, that we have a lot to learn from end-user testing and feedback. It reverses the stodgy old HP model of not writing a line of code (or burning a PC board) until you've sent your ERS and IRS through enough phases of review and editing, then being afraid to deviate from the Gospel later when design issues inevitably show up. :-)

    Of course any model can be abused or misapplied. A big problem with refactoring is the natural tension between perfectionists (like me) who don't know when to stop tinkering ("perfect is the enemy of done") and managers feeling perennial pressure to "paint it yellow and ship it." It's great if rapid and iterative prototyping allows you to test and refine your designs efficiently for maximum value, but it sucks when you're forced to ship "one prototype too soon" and then move on to something else.