The following article was printed in February 1985 of the magazine „Computer Language".
A base article describing the syntax of the Programmers Pseudo Listing (PPL).

Pseudocode syntax


By Namir Clement Shammas


Welcome to CrossXthoughts! It is a new column for all programmers and a platform for sharing algorithms and programming development techniques and solutions.
We will cover a wide variety of subjects, such as data management techniques, interpreters, graphics, and artificial intelligence. I will be using the COMPUTER LANGUAGE Bulletin Board Service (415 957-9370) and CompuServe to interact with readers (but ordinary mail is not completely ruled out!). These media will be used for topic selections, followup discussion on published columns, questions asked by readers, and sharing expert opinions and experiences.
In addition, the column will assist readers with similar interests in contacting each other. This will allow further discussion and exchange and published follow-up. I will maintain SIG lists containing names, addresses, phone numbers, etc. They will be posted on the bulletin boards and also made available through COMPUTER LANGUAGE by written requests. Putting your name on a particular SIG list is done at your request, by writing or through the BBS and CompuServe. The column will also carry out mini-contests awarding books, software packages, and subscriptions in the magazine.

To make this column a crossroad for programmers who use different languages, I will be using pseudocode listings frequently. Pseudocode is also this issue's topic.
To insure good readability and a degree of consistency I am suggesting a syntax for the Programmers' Pseudo Listing (PPL). I have loaded it on a BBS file called NILE, which contains an application program written in Turbo Pascal and the documentation for using it. It checks the PPL syntax and helps in top-down software design process allowing development from general to specific.
Additional advantages gained from using the PPL are:
♦ During software development it is easier and faster to alter and update text than it is to change flowcharts.
♦ The PPL offers programmers flexibility in sharing information. One can generalize certain code segments to either spare the other party irrelevant code or deliberately hide detailed algorithms to protect programming tips and tricks.
♦ To assist top-down software design.
♦ To assist applications development in more than one language or from one to another.
The implementation of a standard PPL, just like any language, is subject to certain syntax and rules. They are of course much more flexible than those for formal languages. Deviating from them is by no means a sacrilege. The general rules are:
Data types and identifiers. This is the area where languages differ greatly. The PPL will leave the choice of how to present data structures up to the programmer.
Labels. The aim of structured languages is to move away from using labels and GOTOs. It is worth pointing out that Modula-2 has not implemented the GOTO statement at all! By contrast, Ada and C allow using the GOTO especially for exiting deeply nested loops. Therefore, labeled GOTOs are allowed. This should benefit those who program in BASIC and FORTRAN. However, I must say — following the example of nonsmoker signs — "Thank you for not GOTOing"
Loops. There are two basic types of loops. The first has a loop counter with starting and ending values — the code in the loop is repeated a fixed number of times. This is the famous FOR-DO loop in Pascal and Modula-2 or the FOR-NEXT in BASIC
The second loop type would execute the enclosed code depending on the success of a conditional test. When the test is located at the beginning of the loop, we have the WHILE-DO, as in Pascal, Modula-2, C, and FORTRAN 77. When the test is carried out at the end of the loop, forcing execution of the code at least once, we have the REPEAT-UNTIL effect. The test can also be carried out anywhere inside the loop in an attempt to exit. This is equivalent to the LOOP-EXIT in Ada and Modula-2.
From the preceding we can see that the different loop types can be presented basically as shown in Listing 1. The INITIALIZE will remind the programmer of any loop initializations; I suggest its presence be mandatory. The word "None" should be used when no action is needed. The LOOP keyword is followed by an optional loop name. The latter is useful to keep track of exiting nested loops (actually, it is an Ada feature).
General loop construct

INITIALIZE <optional set-up>
LOOP <optional name>
BEGIN <no text to simulate REPEAT-UNTIL> or
      <declare loop counter> or
      <Optional test here to EXIT <optional name> >

   loop code with optional test to EXIT <optional name>

   Optional test here to EXIT <optional name>
END LOOP
TERMINATE resolve any pending operations
Listing 1.
The loop BEGIN may contain information to indicate the use of a counter or a conditional test to simulate the WHILE-DO construct. The conditional test can be inserted inside the loop code or at the end. The latter will simulate the REPEAT-UNTIL construct. The END LOOP token need not be followed by a loop name since we expect loops to be logically nested. The TERMINATE key word is used to indicate the action taken to resolve pending data treatment after the loop ends.
Conditional branching. Inspired by languages like C, Pascal, Modula-2 and Ada, I use two types of conditional branching constructs:
1. The well-known IF-THEN construct with ELSE and ELSEIF clauses for more elaborate decision-making. Listing 2 shows the two alternatives when using the IF-THEN clauses.
2. The CASE test is applied when an identifier can be used as a switch to select the appropriate course of action. Listing 3 shows the construct for CASE. The WHEN and OTHERWISE keywords will indicate the beginning of a new CASE option and the end of a previous one, except for the first WHEN.
IF-THEN constructs

IF <Test is true>
THEN
          Outcome # 1
ELSE
          Outcome # 2
END IF

and

IF <Test 1 is true>
THEN
     Outcome # 1
ELSEIF <Test 2 is true>
THEN
     Outcome # 2
ELSEIF <Test 3 is true>
THEN
     Outcome # 3
ELSE
     Outcome # 4
END IF
Listing 2.
CASE construct

CASE <identifier>

     WHEN <value 1 is ture> => Outcome # 1
     WHEN <Value 2 is ture> => Outcome # 2
     .........
     OTHERWISE => Outcome # X

END CASE
Listing 3.
Procedures and functions. Due to the use of plain English words to describe the action taken, we must be able to point out specific calls to procedures and functions. I suggest that the procedure names be enclosed in brackets and function names in braces. The following example shows how a call to a procedure SOLVE is documented:

Set up simulataneous equation and [SOLVE]

Another example is a call to a logical function DiskFull:

IF {DiskFull} THEN warn the user that no space is left

Since the PPL may be involved in early software development stages, the procedure and function declarations follow the main code portion. This allows for a topdown software design. Thus, procedures and functions that are called more often would be located further down in the listing. To declare the code for a procedure or function, it is sufficient to use the keywords PROCEDURE or FUNCTION followed by a name.
Input/Output. This is another aspect of programming where different languages as well as dialects implement differently. We will adopt the following commands:
DISPLAY <list> for screen output
INPUT <list> for keyboard input
PRINT <list> to send output to a printer.
File I/O involves reading and writing of data records. The first command needed by all file I/O is to open it:

OPEN <filename>,<buffer name or number>,<mode>

where the I/O mode is one of the following:
INPUT for data input
OUTPUT for data output
APPEND to append output data to the existing file
RANDOM for random data read and write.
Its counterpart is CLOSE <buffer name or number > to close the file.
For sequential I/O we have READ <buffer>,<data> to input data,
WRITE <buffer>,<data> to output.
For random I/O we have READ <buffer>,<record #>,<data> and
WRITE <buffer>,<record #>, <data> to read and write, respectively.
The SEEK <buffer>,<record> is used to position record pointers to a specific location.
Port communications is carried out in a similar way to file I/O except the modes allowed are, obviously, INPUT and OUTPUT.
Incrementing, decrementing and scaling variables. These operations are used extensively in all languages. Some, like C, offer a shorthand way of stating them. I am adopting the C notation. This is useful in shortening code lines since long variable names would most likely be used for clarity. To increment a variable:

Variable+=Added number

which is equivalent to

Variable=Variable+Added number

and to decrement a variable:

Variable-=Subtracted number
Similarly, scaling a variable by multiplication or division, as in

Variable=Variable*Factor

and

Variable=Variable/Factor

become (Variable*=Factor) and (Variable/=Factor), respectively.
Remarks. For those who want to formalize remarks and comments, borrowing from Ada's syntax is useful. The remark is expressed by at least two consecutive dashes, as in:

--This is a remark
------------This one too!
--------and so is this

Listing 4 shows pseudocode for solving a single nonlinear equation using the Newton-Raphson method. The PPL shown reflects a rather detailed code revealing very specific algorithms.
Listing 5 shows the code for a regression program that will read data from a file and perform a best-fit regression. This is done by subjecting the data read to a combination of mathematical transformations. Each of the latter represents a different regression model.
The code shown will process the data through four models. The slope, intercept and correlation coefficient is calculated for each model. An insertion sort is performed as results are obtained for each model. This allows for the printing of the curve fitting information sorted from best to worst model. The PPL listing reflects the case where a programmer is avoiding detailed coding in certain areas.

Do you have any comments or suggestions concerning PPL? Does the idea of a consistent type of pseudocode appeal to you? Is it too restrictive? Would you like to participate in a SIG-PPL group for further refinement of PPL? Let me hear from you. Please write to me in care of COMPUTER LANGUAGE, 131 Townsend St., San Francisco, Calif. 94107 or contact me through the BBS or CompuServe.
In the next issue I will discuss interactive parsers and interpreters for mathematical equations (i.e., the heart of electronic spreadsheets). If you have any code or algorithms to share, questions to ask, or would like to enrole in the SIG list, drop me a line. Remember that the SIGs are there to help exchange information and, who knows, perhaps find your next software coauthor!
PPL listing for solving a single nonlinear equation
using the Newton-Raphson method

PROGRAM Root

Version 1.0   June 10, 1984
LAST UPDATE :  06-15-84       12:22:23

INPUT Guess, Accuracy, Maximum

  INITIALIZE Set Counter = 0
             Set Goflag True
  LOOP

-- The token below is not followed by anything as part of
-- simulating the REPEAT-UNTIL loop
  BEGIN

        IF  abs(Guess) > 1   THEN    Increment = 0.01 * Guess
                             ELSE    Increment = 0.01
        END IF

        Delta_X = 2 * Increment * {F(Guess)} /
                 ({F(Guess + Increment)} - {F(Guess + Increment)]

        Guess -= Delta_X

        Counter += 1
        IF   Counter > Maximum   THEN   Goflag is False   END IF

        When (abs(Delta_X) <= Accuracy) OR (Goflag is False) EXIT

  END LOOP
 TERMINATE   None
 IF   Goflag is True     THEN
                           DISPLAY Guess and Counter
                         ELSE
                           DISPLAY Message for divergence
 END IF

END PROGRAM -- This is optional
---------------------------------------------------------------
FUNCTION (F(X)}
-- User-- function

    F = EXP(X) - 3 * X * X

END

END PPL

---------------------------------------------------------------
Listing 4.
PPL listing for best-curve fit

PROGRAM BEST_FIT

Version 1.0   June 10, 1984
LAST UPDATE :  06-15-84       12:22:23

INPUT Filename           -- Get name of data source
OPEN Filename, #1, INPUT
READ #1,Number_of_data   -- Read the amount of data
  INITIALIZE   None      -- Loop to read the (X,Y) data pairs
  LOOP
  BEGIN   For counter = 1 to Num_of_data
     READ #1,X(counter),Y(counter)
  END LOOP
  TERMINATE    CLOSE #1 -- close buffer

Set Num_Model = 4    -- This sets number of models

[DO REGRESSION]

Print sorted results

END PROGRAM
---------------------------------------------------------------
PROCEDURE [DO REGRESSION]

  INITIALIZE None
  LOOP   Outer
  BEGIN   For model = 1 to Num_Model
       INITIALIZE   Set regression summation to zero
       LOOP   Summmations
       BEGIN   For count = 1 to Num_of_data
          [Transform]
          Update summations using X and Y
       END LOOP   Summations
       TERMINATE   None
     Calculate Slope, Intercept and correlation coefficient
     -- Perform insertion sort using the values of the
     -- correlation coefficient
        [SORT]
  END LOOP   Outer
  TERMINATE   None

END

---------------------------------------------------------------
PROCEDURE [Transform]

  CASE   model
       WHEN 1 => X = X(count); Y = Y(count)
       WHEN 2 => X = Log(X(count)); Y = Y(count)
       WHEN 3 => X = X(count); Y = Log(Y(count))
       WHEN 4 => X = Log(X(count)); Y - Log(Y(count))
  END CASE

END

END PPL -- This must be included in every PPL listing using
        -- program NILE.PAS
Listing 5.

HTML customization by Werner Cirsovius
January 2015
© CL Publications