GENERIC

GENERIC is a data type attribute that is used when a generic name is declared for a set of entry references and their descriptors. Its format is:

generic-name GENERIC (references)

where references are:

entry-reference-1 WHEN (generic-descriptor)
entry-reference-2 WHEN (generic-descriptor)
entry-reference OTHERWISE

where generic-descriptor is a data attribute such as FIXED, FLOAT, BINARY, etc.

Additional attributes allowed are ALIGNED, UNALIGNED, ASSIGNABLE, NONASIGNABLE, INOUT, INONLY, OUTONLY, CONNECTED, NONCONNECTED, BIGENDIAN, and OPTIONAL. The attributes ASSIGNABLE, NONASIGNABLE, CONNECTED, and/or NONCONNECTED, if specified, are ignored.

Entry references must not be subscripted or defined. The same entry reference can appear more than once within a single GENERIC declaration with different lists of descriptors.

Each generic descriptor corresponds to a single argument. It specifies an attribute that the corresponding argument must have so that the associated entry reference can be selected for replacement.

Structures or unions cannot be specified.

If a descriptor is not required, it is represented by an asterisk. If there is a descriptor that represents the absence of all arguments in the invoking statement, it is expressed by omitting the generic descriptor in the WHEN clause of the entry.

When an invocation of a generic name is encountered, the number of arguments specified in the invocation and their attributes are compared with the descriptor list of each entry in the set. The first entry reference for which the descriptor list matches the arguments both in number and attributes replaces the generic name.

In the following example, an entry reference that has exactly one descriptor matching any combination of the attributes FIXED, BINARY, FLOAT, and/or DECIMAL, is searched for. If there are no matching entries, the otherwise clause is selected.

*PROCESS FLAG(I);
 mysqrt: proc options(main);

   dcl sqrt generic (
         mf_sqrti when (fixed bin),
         mf_sqrtf when (float dec),
         mf_sqrtd when (float bin),
         mf_sqrterror otherwise );

    dcl i fixed bin(15) init(9),
        j fixed bin(31) init(16),
        f float dec(6)  init(25.0),
        d float bin(52) init(36.0);

    call sqrt(i);
    call sqrt(j);
    call sqrt(f);
    call sqrt(d);
    call sqrt('e');

    mf_sqrti: proc (x);
        dcl x fixed bin(31);
        put skip list (procedurename() || ' selected.');
    end;

    mf_sqrtf: proc (x);
        dcl x fixed dec(16);
        put skip list (procedurename() || ' selected.');
    end;

    mf_sqrtd: proc (x);
        dcl x float bin(52); 
        put skip list (procedurename() || ' selected.');
    end;

    mf_sqrterror: proc(g);
        dcl g char;
        put skip list (procedurename() || ' selected.');
    end;
 end;

When executed, it prints:

MF_SQRTI selected. 
MF_SQRTI selected. 
MF_SQRTF selected. 
MF_SQRTD selected. 
MF_SQRTERROR selected.

The entry with the OTHERWISE clause is selected, if present, when an entry with the exact number of descriptors with the exact attributes cannot be found.

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

*PROCESS FLAG(I);
test: proc options(main);

    dcl dims generic (
        dim1 when (fixed, (*)),    /* 1st param has fixed attr, 2nd param has one dimension */
        dim2 when (fixed, (*,*)),  /* 1st param has fixed attr, 2nd param has two dimensions */
        err  otherwise );

    dcl a fixed bin;
    dcl b float bin;

    dcl arr1 (20) fixed bin;
    dcl arr2 (10,2) fixed bin;

    call dims(a, arr1);    /* dim1 called */
    call dims(a, arr2);    /* dim2 called */
    call dims(b, arr2);    /* err called, 1st param mismatch */

    dcl dim1 entry(fixed bin, (*) fixed bin) ext;
    dcl dim2 entry(fixed bin, (*,*) fixed bin) ext;
    dcl err  entry(any, any) ext ;
end;

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.