[comp.software-eng] Soft-Eng digest v5n20

soft-eng@MITRE.ARPA (Alok Nigam) (07/25/88)

Soft-Eng Digest             Sat, 23 Jul 88       V: Issue  20

Today's Topics:
                  Basics of Program Design (2 msgs)
            Basics of Program Design (The next Generation)
----------------------------------------------------------------------

Date: Thu, 07 Jul 88 13:37:27 PDT
From: PAAAAAR%CALSTATE.BITNET@cunyvm.cuny.edu
Subject: Basics of Program Design

Sorry if I repeat something said earlier but
the assorted mail systems I use regularly lose, shuffle and delay issues
of this and other newsgroups (please don't ask for details...).

In Soft-Eng Digest             Tue,  5 Jul 88       V: Issue  16
pacbell!ptsfa!jmc@ames.arpa  (Jerry Carlin) quotes
>In article <900@td2cad.intel.com> brister@td3cad.UUCP (James Brister) writes:
>>What I mean is: do experienced programmers usually write flow charts,
>>or pseudo code. Do they write the whole program out by hand first or
>>build it up in their favorite editor?
>>
>>What's a good way to organize the writing process? I have all these
>>great ideas running around in my head that I find difficult to get
>>out without making mistakes in the task itself.

The one essential piece of advice that I can share it is that
you *must* have some framework to gives you one thing to concentrate at
a time - definite series of focal points and processes to do.  Such a set
of definite activities is called a 'method'.  The 'best method' depends
on the context in which it fits.  My method starts by making dictionary
that defines all the words and phrases that are used by the client/user/etc
to describe data and other things of interest. This is done using
a notation that is parallel to those used to structure programs.
The structure of the data determines the most maintainable structure
for the program...

If I don't have a specification to work from then I'm forced to start
by thinking about what the program is going to be a model of, and what it
is going to replace, what its environment consists of, etc
and only then move on to defining the data.

pacbell!ptsfa!jmc@ames.arpa  (Jerry Carlin)
 replied to brister@td3cad.UUCP (James Brister):
>Good question! In spite of all the theory and people that say we can
>reduce programming to a "factory", it is still a "craft" (in the
>highest sense). There are a lot of aids, and experienced people will
>use them when appropriate. It is almost never (as in <1%) a good idea
>to code at the keyboard without knowing what you are doing.

How things change!  I have been studying methods since 1971 when
I recognised that I didn't know how to design programs - but that I needed
to find out how to  *prepare* for writing the code. Jerry summarizes 90% of
what I learnt between 1971 and 1979.

>On the other hand, for relatively simple programs, I'll code the comments
>first, then the mainline and then fill in the functions without ever

This type gives the stepwise refinement method suggested by Pete Naur
in the 70's.

There are other kinds of comments.
Many text books and papers state that you should
write *assertions* which state what you want to be true at that
point in the program.  These are harder to write (almost impossible)
but are helpful for (1) proving that the current level does what it is supposed
to and (2) specifying what each step needs to have do at the next level of
refinement.
        There are about 5 people world wide who use assertions in this way
        and they all earn their cash by writing books about programming not by
        programming...
        :-)

>The best way to organize the process comes with experience: some
>problems need "data structuring", some "data flow", some "object-oriented"
>etc. Beware of snake-oil. There is no magic elixer.

I'll come back to my favorite snake-oil in a moment.

>By the way, you will always make mistakes. Murphy's law lives.

The answer to mistakes is
 - "the first fool who comes along will see your mistake".
In other words the wise organization will pay
another programmer or two to inspect what you have done before it's
compiled/run/tested/...
IBM paid Make Fagin a $50,000 prize for implementing quality control
INSPECTIONS.
(to be continued...)

------------------------------

Date: 15 Jul 88 17:31:30 GMT
From: tektronix!teklds!amadeus!karenc@bloom-beacon.mit.edu  (Karen Cate;6291502;92-734;LP=A;60.D)
Subject: Basics of Program Design

Warning:  This is fairly long, but someone may find it interesting...

In article <1339@hp-sdd.HP.COM> nick@hp-sdd.UUCP (Nick Flor) writes:
>In article <3675@teklds.TEK.COM> karenc@amadeus.UUCP (Karen Cate) writes:
>>
>>     We did our best guess, which looked something like a broom:  one
>>     input, a bubble, and a bunch of "parallel" outputs (which roughly
>>     corresponded to each menu option).  We took that to the instructor
>>     with the comment that we felt our system would be more suited to
>>     control flow diagrams (essentially a flow chart).  The instructor
>>     agreed, so we based the rest of our design work on those.
>>
>Although it was easier for you to model your system in terms of control
>flow, let me ask you how you made the transition from control flow
>diagrams to functions and data. i.e. from the control flow diagrams, how did
>you determine what functions and data types you needed in your program.
>
     The main reason this worked was because we had an easily and well
     defined "data base".  The data objects/structures "fell" right out
     of the Product Definition.  First let's remember the application.
     It was a system designed to keep track of stock data for a limited
     "portfolio" and display the data in several different forms.
     The data was to enter the "system" in one of two different ways, and
     "leave" the system (i.e. be displayed) in several different ways.

     The fact that the data structures were so obvious, was one of the
     reasons we felt control flow was so much more appropriate.  This
     is a very small project compared to what most of "us" (i.e. soft-eng
     group readers) are accustomed to.

     We did not have to write the program, just design it.  We went
     through a multi-stage design process.  Each step produced a
     document:

        1.  Product Definition
             -Problem Definition
             -System Justification
             -Solution Strategy
             -Priorities for System Features
             -System Acceptance Criteria
             -Glossary

        2.  Software Requirements Specification
             -Product Overview and Summary
              o General Overview
              o Data Acquired
              o Local Data Storage
              o Data Entry
              o Data Representation
              o On-line help
              o Statistics
             -External Interfaces and Control Flow
              o User Displays and Reports
              o Command Summary (Softkey def'ns)
              o High Level Control Flow Diagram
             -Exception Handling
             -Early Subsets and Implementation Priorities
             -Forseeable Modifications and Enhancements
             -Design Guidelines
             -Glossary

        3.  Architectural Design Specification
            -Control Flow Diagrams
            -Conceptual Layout of Data Structures and Data Bases
            -Names, Dimensional Units, and Other Attributes of Data Objects
            -Name and Functional Description for Each Module
            -Interface Spec. for Each Module
            -Timing Constraints
            -Exception Conditions
            -Glossary

        4.  User's Manual (preliminary)

        5.  Project Legacy Report
            -Project Description
            -Initial Expectations
            -Current Status
            -Remaining Areas of Concern

    The Control Flow Diagram:

                               +--------+
                               |  Main  |
                               +--------+
                                    |
        +---------------------------------------------------------+
        |                 |                   |                   |
     +-------+       +----------+         +--------+          +--------+
     | File  |       | DataComm |         | Report |          | System |
     | Mgmt. |       +----------+         +--------+          +--------+
     +-------+         |                       |
       |               +-Remote         +-------------+
       +-Store         | Retrieve       |             |
       |               |             +------+     +--------+
       +-Edit          +-Local       | HLCV |     | Report |
       |                 Retrieve*   +------+     +--------+
       +-Export                       |             |
       |                              +-Local       +-Local
       +-Import                       | Retrieve*   | Retrieve*
                                      |             |
                                      +-HLCV        +-Trend
                                      | Table       | Table
                                      |             |
                                      +-HLCV        +-Trend
                                        Graph         Graph

    *-Local Retrieve is called from three places.


    Each "box" and "leaf" was a function.  The "box" functions merely
    put up a menu, and called the correct routine depending on the
    user's choice.  Each "leaf" function accessed the "data base"
    (which was actually to be implemented as a linked list of records
    in RAM, and stored in two files on disk), massaged the data into
    the correct format, and displayed it for the user.  The local and
    remote retrieval functions pulled data into RAM (either from a
    local disk, or some "electronic news retrieval service").

    We felt that no data "flowed" through the system, only through the
    leaves [i.e: (Data Base)->(Graph Fcn)->(User)].  Data flow didn't
    make any sense.

    One reason we chose this topic was that one member of my group
    needed such a tool at that time.  He wanted to actually implement
    it that summer...  I lost touch with them over the summer, so I
    don't know if he ever did.  [If any of you guys are reading this, I'd
    love to hear from you!]
>
>then again, I could be wrong...
>
    Not necessarily.  The point I was trying to make was that "it depends".
    Most "traditional" or business related software systems really do
    rely on data flow.  Their purpose is to move large amounts of data
    to and from many places.  Not ALL applications do this, as I tried
    to show with my example.  It may still not make much sense, but I'm
    not willing to type in my 60 or so pages of documentation.  I've
    already spent too long on this...  I feel strongly about it though...
    Too many people do things "this way" because that's what so-and-so
    said was "the right way", even though it's not the most intelligent
    way of doing it.  [Gee, that sounds condiscending.  It was not meant
    to be.]  I fought that philosophy all through college -- having
    such and so percent comments (which was so much wasted time, in many
    cases, it couldn't be in a block at the beginning of the procedure,
    but virtually every line had to be explained individually...),
    Warnier-Orr diagrams that were incredibly misleading (but required
    none-the-less), etc and so on.  Several times, I looked at what I
    handed in when I got it back and noticed glaring errors that were
    not caught by whoever did the grading (99% of the time, that person
    was not the teacher).

    Gag.  Sorry this is so long.  I've given up trying to edit for
    brevity.  I end up leaving too much out.

------------------------------

Date: Thu, 07 Jul 88 13:47:03 PDT
From: PAAAAAR%CALSTATE.BITNET@cunyvm.cuny.edu
Subject: Basics of Program Design (The next Generation)

spar!freeman@decwrl.dec.com  (Jay Freeman) writes
>That's a fascinating subject; there are probably as many different answers
>as there are programmers.

Yes - and most of them seem to have the wrong answer (NO SMILEY HERE)

>  When I am doing a big system, I usually spend as
>long a time as possible in a design phase, thinking about data structures,
>algorithms and control flow at a quite abstract level, often accumulating
>large stacks of notes on paper, backs of envelopes and so on.
...
This is an environment where Jay either has a clear specification
to work from and can proceed directly to the internals of the program or
Jay can choose the user interface, functions, etc.

>A key part of the design is figuring out how to bring the system up; I'm
>sure your professors tell you that getting everything all written, then
>compiled, then starting to test, is NOT the way!  It's important to define
>a development path that starts with only a few pieces of the whole thing
>up and running, and ends with a complete system, such that you can move
>from point to point on the path by adding small modules to the system
>...
>...one
>does prototypes and throws them away, and so on.

Tom Gilb has been saying this since the early 80's so Jay is in good company!
Brookes said it in the Mythical Man Month: "Plan to throw one away"
Experience has proved the worth of prototypes to me.  The only
excuse for starting with code is if the code is a prototype.

>there are several ways to think about the order in which to implement various
>modules.  Top-down is nice and logical, but often leads to lots of stub
>functions which are difficult to test until you have coded out to the leaves
>of the call graph

It is easy to confuse the following distinct methods:
        the method of design
        the method of construction
        the method of testing.

A program can be designed left-to-right, implemented bottom up and tested
right-to-left!

The other confusion is between what you might call
        exterior and interior design.
Exterior design selects what the programs do and how the users interact with
them. Interior design is concerned with how to structure and code a program to
fit the given exterior design.  Exterior design is an art compared to the techni
terior design.  Done this way you get engineeering.

In the past software was so difficult that a programmer could get
away with doing an excelent interior design and claiming that any thing else
would be (1) to slow (2) too big (3) not done here (4) a waste of time...
however bad the result was from the user's point of view.  In the 80's there
is a little more competition and so exterior design has to be separated out.

An programmer with more experience than I had  defined top down design as
        "Building Castles in the Air"
The main problem is that most top-down methodologists
tend to use hand waving to determine either the boundaries between the
modules and/or the structure of each module is.
There isn't even a common agreement as to what a "module" is!

>Bottom-up is useful if you are sure what primitives you are going to need;

The same aged programmer defined Bottom-up as
        "Flying a Kite"

There was a series of articles in "Computer Language" during 1987-1988 by PJ
(Use my tools) Plauger which is a thourough tour threw several methods:
        Top-down
        bottom-up
        left-right   - syntax directed compilers for example
        right-left   - structure follows the output
           (Very like what Jean Dominick Warnier proposed)
        Data Flows
        outside-in   - where the program is a pipe line with a left-right
                       design outputing data into a right-left program.
           (This last is pretty much Jackson's JSP)
I've collect half-a-dozen more... JSD, Object Oriented Design, Dynamic Design

One day there may be a GRAND SYNTHESIS of all these methods...but don't
hold your breath waiting for it...

>It is often very handy to use a system that provides some kind of top-level
>interpreter

Jon Bentley of AT&T makes a strong case for using the UNIX tools (especially
'awk') for prototyping - see his "Programming Pearls" books...
Again from experience, prototyping has paid off many times.

>And in that context it is a useful rule of thumb never to create a data
>structure without also creating a function that prints it out in a form
>that humans can read; you end up inserting that function time after time
>as a debugging aid.

Jay hits the nail on the thumb here (:-)
Seriously - Parnas:
        Data Structures should be implemented inside a shell
        of useful procedures and functions that hide how the data is stored
        are but allow it to be used easilly.
(Not in those words)
Printing a data object is *one* of many functions that should surround
a data structure.  Document them, put'em in a library and keep reusing them!

>My, how I ramble.  Hope this is useful or at least provokes thought.
So do I.

pdn!larry@uunet.uu.net  (Larry Swift) writes
>Flow charts or state diagrams (I prefer the former) are better thought
>organizers, but are difficult to maintain, so pseudo code usually wins out.

To organise thoughts use an outliner that fits your personal workstation
and habits - ThinkTank, More, etc all come to mind...

There exist notations for structured designs that combine advantages of
flowcharting and psedocode. Many have rediscovered or re-invented
Rob Wittey's Dimensional Charts. Carma McClure and James Martin present
Action Diagrams in their book "Diagramming Techniques for the Analysists
and Programmers".

Advert. If you need wants more detail - I can mail copies of papers I have
        published on methods.

------------------------------

End of Soft-Eng Digest
******************************

EGNILGES@pucc.Princeton.EDU (Ed Nilges) (07/26/88)

IN Soft-Eng digest v5n20 , PAAAAAR%CALSTATE.BITNET@cunyvm.cuny.edu
writes:
>
>
>There are other kinds of comments.
>Many text books and papers state that you should
>write *assertions* which state what you want to be true at that
>point in the program.  These are harder to write (almost impossible)
>but are helpful for (1) proving that the current level does what it is supposed
>to and (2) specifying what each step needs to have do at the next level of
>refinement.
>        There are about 5 people world wide who use assertions in this way
>        and they all earn their cash by writing books about programming not by
>        programming...
>        :-)
 
 
The attitude evidenced by this posting is one of the reasons why software
continues to be late and hard to maintain.  Assertions are only
impossible to write when the software has not been designed in
a structured and modular fashion.
 
The Microsoft C compiler provides the following function in its run
time library:
 
     #include <assert.h>
 
     void assert(expression)
 
     "The assert routine prints a diagnostic message and terminates
      the calling process if expression is false (0)."
 
I am using assert() in developing a largescale system for a client.  If
the preprocessor symbol DEBUG is on, the asserts are generated.  Here
is a typical use:
 
a1_getparms(a1_ArgCount, a1_ArgValue)
     int a1_ArgCount;
     char **a1_ArgValue;
     .
     .
     .
     #if DEBUG
         assert( a1_ArgCount>=0 && a1_ArgValue!=NULL && *a1_ArgValue!=NULL );
     #endif
 
 
My assertions do not PROVE my software correct...any more than the designers
of the Golden Gate Bridge (reference 2) could PROVE mathematically that
the GG Bridge would stay up and be beautiful to boot.  I don't feel that
it is possible to PROVE software correct.  But I am not loth to try
whatever tools are available to move the software towards correctness.
 
REFERENCES
 
1.  Microsoft Corporation, Microsoft C Compiler for the MS-DOS Operating
    System: Run-Time Library Reference, p. 104.  1986...release 4.x.
 
2.  John van der Zee, The GATE:The True Story of the Design and Construc-
    tion of the Golden Gate Bridge.  New York, 1986: Simon and Schuster.