One of the simplest PL/I programs is:

   World: Procedure options(main);
          Put List( 'Hello world' );

          End World;







In the following example, an entry reference that has exactly two descriptors with the attributes DECIMAL or FLOAT, and BINARY or FIXED is searched for.

       declare Calc generic (
                    Fxdcal when (fixed,fixed),
                    Flocal when (float,float),

                    Mixed  when (float,fixed),
                    Error otherwise);
       Dcl     X decimal float (6),
               Y binary fixed (15,0);



               Z = X+Calc(X,Y);


If an entry with the exact number of descriptors with the exact attributes is not found, the entry with the OTHERWISE clause is selected if present. In the previous example, Mixed is selected as the replacement.

In a similar manner, an entry can be selected based on the dimensionality of the arguments.

       dcl  D generic (D1 when ((*))),

                       D2 when((*,*))),
            A(2),
            B(3,5);
       call D(A);      /* D1 selected because A has one dimension  */
       call D(B);      /* D2 selected because B has two dimensions */

 

If all of the descriptors are omitted or consist of an asterisk, the first entry reference with the correct number of descriptors is selected.

An entry expression used as an argument in a reference to a generic value matches only a descriptor of type ENTRY. If there is no such description, the program is in error.





/* PL/I procedure for Shell Sort. */
 /* Copyright (c) 1996 by R. A. Vowels, from "Introduction to PL/I, Algorithms, and               */
 /* Structured Programming".  All rights reserved.                                                */
 /* This subroutine sorts an array by sorting continually-changing sub-groups.                    */
 SHELL_SORT:

PROCEDURE (A) OPTIONS (REORDER);

      /* INCOMING:   A = an array whose elements are to be sorted.                                */
      /* OUTGOING:   A = the sorted array.  Elements are in ascending order.                      */

DECLARE A(*) FIXED BINARY;
      DECLARE Temp                 FIXED BINARY;
      DECLARE (J, K, N)            FIXED BINARY;
      DECLARE Gap                  FIXED BINARY UNSIGNED;

N = HBOUND(A, 1); /* The number of elements in the array A. */

      Gap = N/2;                            /* The initial gap is half the number of elements.    */

DO WHILE (Gap >= 1); /* We are done after the gap is 1, when all */

                                            /* elements are examined in the next loop:            */

         /* Perform a Ranking Sort on selected elements.                                          */

DO K = 1 TO N-Gap;

            IF A(K) > A(K+Gap) THEN         /* Select elements every Gap positions apart . .      */

               DO;
                  Temp = A(K+Gap);
                  DO  J = K  TO  1  BY  -Gap  WHILE (A(J) > Temp);

                     A(J+Gap) = A(J);       /* Leapfrog by Gap locations.                         */
                  END;
                  A(J+Gap) = Temp;
               END;
         END;
         Gap = Gap/2;                       /* Halve the gap for the next Ranking Sort.           */

END;
END SHELL_SORT;

/* PL/I program to create a one-way linked list.                                             */

/* Copyright (c) 1996 by R. A. Vowels, from "Introduction to PL/I, Algorithms, and               */
/* Structured Programming".  All rights reserved.                                                */

/* This procedure creates a one-way linked list, and then traverses that list.                    */
/* The procedure reads in integer values in free format, and stores each value in a node.         */
/* As each value is read in, a node is created, the value is placed in the node, and the          */
/* node is attached to the head of the list.  The last of the values read in is zero (which       */
/* causes the list-creation loop to terminate).  Finally, the list is traversed.                  */
CREATE:

PROCEDURE OPTIONS (MAIN);
DECLARE 1 Node BASED (Head), /* A template for the node & the pointer to it. */

              2 Value             FIXED BINARY,  /* For the value.                               */
              2 Ptr               POINTER;       /* For a pointer to the next node.              */
     DECLARE Current              POINTER;       /* An auxiliary pointer.                        */
     DECLARE Head                 POINTER;
     DECLARE NULL                 BUILTIN;

     /* The list is created by placing each new item at the head of the list.                    */
     PUT LIST ( 'This program creates a linked list by attaching to the head of the list.' );
     PUT SKIP LIST ( 'Please type the values of each node; the last value is zero:' );

     /* SECTION TO CREATE A LINKED LIST.                                                         */
                                                 /* ORGANIZE THE HEAD.                           */

ALLOCATE Node; /* Create the node. */

     GET LIST (Head -> Value);                   /* Place a value in the node.                   */
     Current = Head;                             /* Point at the node.                           */
     Current -> Ptr = NULL;                      /* A null link for the node (which is also the  */
                                                 /* tail).                                       */

                                                 /* APPEND NODES.                                */
     /* A loop to create other nodes and to attach them to the head of the list.                 */
     DO WHILE (Head -> Value ^= 0);              /* Until a sentinel of zero is read in.         */
        ALLOCATE Node;                           /* Create a new node, to become the head.       */
        GET LIST (Head -> Value);                /* Read in a value & place it in the new node.  */
        Head -> Ptr = Current;                   /* Make the new node point at the head of the   */
                                                 /* existing list.                               */
        Current = Head;                          /* Point at the new node, which has become the  */
                                                 /* head of the list.                            */
     END;

     /* SECTION TO TRAVERSE the linked list, printing each element as we go.                     */
     PUT SKIP LIST ( 'The elements in the list are:' );
     Current = Head;                             /* Start at the Head node.                      */
     DO WHILE (Current ^= NULL);                 /* Until we reach the tail.                     */
        PUT LIST (Current -> Value);
        Current = Current -> Ptr;                /* Point at the next node.                      */
     END;
  END  CREATE;

IN PRAISE OF PL/I

By Lou Marco

What programming language has been available for more than 20 years, is used by hundreds of thousands of mainframe programmers, has clear, crisp syntax and supports the following features?