Jackson structured programming

From Wikipedia, the free encyclopedia
Jump to: navigation, search
Example of a JSP diagram.

Jackson structured programming (JSP) is a method for structured programming based on correspondences between data stream structure and program structure. JSP structures programs and data in terms of sequences, iterations and selections, and as a consequence it is applied when designing a program's detailed control structure, below the level where object-oriented methods become important.[1][2]

Introduction[edit]

Michael A. Jackson originally developed JSP in the 1970s. He documented the system in his 1975 book Principles of Program Design.[3] Jackson's aim was to make COBOL batch file processing programs easier to modify and maintain, but the method can be used to design programs for any programming language that has structured control constructs, languages such as C, Java and Perl. Despite its age, JSP is still in use and is supported by diagramming tools such as Microsoft's Visio and CASE tools such as Jackson Workbench [4]

Jackson Structured Programming was seen by many as related[5] to Warnier structured programming,[6] but the latter method focused almost exclusively on the structure of the output stream. JSP and Warnier's method both structure programs and data using only sequences, iterations and selections, so they essentially create programs that are parsers for regular expressions which simultaneously match the program's input and output data streams.

Because JSP focuses on the existing input and output data streams, designing a program using JSP is claimed to be more straightforward than with other structured programming methods, avoiding the leaps of intuition needed to successfully program using methods such as top-down decomposition.[7]

Another consequence of JSP's focus on data streams is that it creates program designs with a very different structure to the kind created by the stepwise refinement methods of Wirth and Dijkstra. One typical feature of the structure of JSP programs is that they have several input operations distributed throughout the code in contrast to programs designed using stepwise refinement, which tend to have only one input operation. Jackson illustrates this difference in Chapter 3 of Principles of Program Design.[3] He presents two versions of a program, one designed using JSP, the other using "traditional" methods.

Structural equivalent[edit]

The JSP version of the program is structurally equivalent to

String line;

line = in.readLine();
while (line != null) {
    int count = 0;
    String firstLineOfGroup = line;

    while (line != null && line.equals(firstLineOfGroup)) {
        count++;
        line = in.readLine();
    }
    System.out.println(firstLineOfGroup + " " + count);
}

and the traditional version of the program is equivalent to

String line;

int count = 0;
String firstLineOfGroup = null;
while ((line = in.readLine()) != null) {
    if (firstLineOfGroup == null
            || !line.equals(firstLineOfGroup)) {
        if (firstLineOfGroup != null) {
            System.out.println(firstLineOfGroup + " " + count);
        }
        count = 0;
        firstLineOfGroup = line;
    }
    count++;
}
if (firstLineOfGroup != null) {
    System.out.println(firstLineOfGroup + " " + count);
}

Jackson criticises the traditional version, claiming that it hides the relationships which exist between the input lines, compromising the program's understandability and maintainability by, for example, forcing the use of a special case for the first line and forcing another special case for a final output operation.

The method[edit]

JSP uses semi-formal steps to capture the existing structure of a program's inputs and outputs in the structure of the program itself.

The intent is to create programs which are easy to modify over their lifetime. Jackson's major insight was that requirement changes are usually minor tweaks to the existing structures. For a program constructed using JSP, the inputs, the outputs, and the internal structures of the program all match, so small changes to the inputs and outputs should translate into small changes to the program.

JSP structures programs in terms of four component types:

  • fundamental operations
  • sequences
  • iterations
  • selections

The method begins by describing a program's inputs in terms of the four fundamental component types. It then goes on to describe the program's outputs in the same way. Each input and output is modelled as a separate Data Structure Diagram (DSD). To make JSP work for compute-intensive applications, such as digital signal processing (DSP) it is also necessary to draw algorithm structure diagrams, which focus on internal data structures rather than input and output ones.

The input and output structures are then unified or merged into a final program structure, known as a Program Structure Diagram (PSD). This step may involve the addition of a small amount of high level control structure to marry up the inputs and outputs. Some programs process all the input before doing any output, whilst others read in one record, write one record and iterate. Such approaches have to be captured in the PSD.

The PSD, which is language neutral, is then implemented in a programming language. JSP is geared towards programming at the level of control structures, so the implemented designs use just primitive operations, sequences, iterations and selections. JSP is not used to structure programs at the level of classes and objects, although it can helpfully structure control flow within a class's methods.

JSP uses a diagramming notation to describe the structure of inputs, outputs and programs, with diagram elements for each of the fundamental component types.

A simple operation is drawn as a box.

A box labeled 'A'
An operation

A sequence of operations is represented by boxes connected with lines. In the example below, operation A consists of the sequence of operations B, C and D.

A box labeled 'A' connected to three boxes below it labeled 'B', 'C' and 'D'
A sequence

An iteration is again represented with joined boxes. In addition the iterated operation has a star in the top right corner of its box. In the example below, operation A consists of an iteration of zero or more invocations of operation B.

A box labeled 'A' connected to a box labeled 'B' below it with a star in the top right corner
An iteration

Selection is similar to a sequence, but with a circle drawn in the top right hand corner of each optional operation. In the example, operation A consists of one and only one of operations B, C or D.

A box labeled 'A' connected to three boxes below it labeled 'B', 'C' and 'D' each with a circle in the top right hand corner
A selection

A worked example[edit]

As an example, here is how a programmer would design and code a run length encoder using JSP.

A run length encoder is a program which takes as its input a stream of bytes. It outputs a stream of pairs consisting of a byte along with a count of the byte's consecutive occurrences. Run length encoders are often used for crudely compressing bitmaps.

With JSP, the first step is to describe the structure of a program's inputs. A run length encoder has only one input, a stream of bytes which can be viewed as zero or more runs. Each run consists of one or more bytes of the same value. This is represented by the following JSP diagram.

JSP RLE input.png
The run length encoder input

The second step is to describe the structure of the output. The run length encoder output can be described as zero or more pairs, each pair consisting of a byte and its count. In this example, the count will also be a byte.

JSP RLE output1.png
The run length encoder output

The next step is to describe the correspondences between the operations in the input and output structures.

JSP RLE correspondence.png
The correspondences between the run length encoders inputs and its outputs

It is at this stage that the astute programmer may encounter a structure clash, in which there is no obvious correspondence between the input and output structures. If a structure clash is found, it is usually resolved by splitting the program into two parts, using an intermediate data structure to provide a common structural framework with which the two program parts can communicate. The two programs parts are often implemented as processes or coroutines.

In this example, there is no structure clash, so the two structures can be merged to give the final program structure.

JSP RLE program.png
The run length encoder program structure

At this stage the program can be fleshed out by hanging various primitive operations off the elements of the structure. Primitives which suggest themselves are

  1. read a byte
  2. remember byte
  3. set counter to zero
  4. increment counter
  5. output remembered byte
  6. output counter

The iterations also have to be fleshed out. They need conditions added. Suitable conditions would be

  1. while there are more bytes
  2. while there are more bytes and this byte is the same as the run's first byte and the count will still fit in a byte

If we put all this together, we can convert the diagram and the primitive operations into C, maintaining a one-to-one correspondence between the code and the operations and structure of the program design diagram.

#include <stdio.h>
#include <stdlib.h>
 
int main(int argc, char *argv[])
{
    int c;
 
    c = getchar();
    while (c != EOF) {
        int count = 1;
 
        int first_byte = c;
 
        c = getchar();
 
        while (c != EOF && c == first_byte && count < 255) {
            count++;
            c = getchar();
        }
 
        putchar(first_byte);
        putchar(count);
    }
    return EXIT_SUCCESS;
}

Criticism[edit]

This method will work only when translation from input to output is equivalent to a context-free grammar.[citation needed]

See also[edit]

References[edit]

  1. ^ Wieringa, R (Dec 1998), "A survey of structured and object-oriented software specification methods and techniques", Comput Surv (ACM) 30 (4): 459–527, doi:10.1145/299917.299919 .
  2. ^ Henderson-Sellers, Brian; Edwards, JM (Sep 1990), "The object-oriented systems life cycle", Commun (ACM) 33 (9): 142–59, doi:10.1145/83880.84529 .
  3. ^ a b Jackson, MA (1975), Principles of Program Design, Academic .
  4. ^ Ourusoff, Nicholas (2003). "Using Jackson Structured Programming (JSP) and Jackson Workbench to Teach Program Design" (PDF). InSite 2003. Informing Science. Retrieved 2008-02-18. 
  5. ^ Orr, KT (1980), "Structured programming in the 1980s", Proceedings of the ACM 1980 Annual Conference, New York, NY: ACM Press, pp. 323–26 .
  6. ^ Warnier, JD (1974), Logical Construction of Programs, NY: Van Nostrand Reinhold .
  7. ^ Sorensen, K; Verelst, J (2001), "On the conversion of program specifications into pseudo code using Jackson structured programming", Journal of Computing and Information Technology 9 (1): 71–80, doi:10.2498/cit.2001.01.06 .

External links[edit]