A MAKE statement may look like this
MAKE ODD,XYZ; WEIRD,TQL
and declares that variables of type &"ODD" are to occupy the same pattern of storage as the variable XYZ either does occupy, if it is a normal variable, or, if XYZ is a dummy variable, the pattern of storage that it would have occupied had it not been a dummy variable. As well, it declares the same thing concerning variables of the type WEIRD and the variable TQL.
Recommended @-comments (if used):
MAKE type-name @LIKE, variable-name @AND;...
with only &'LIKE' available as a substitute.
Note that the same real or dummy variables may be used directly or indirectly in MAKE statements which create related types without conflict, since, unlike EQUIVALENCE, a MAKE statement does not involve the actual variables to which it refers directly, it only copies their structure.
Where XYZ is an actual variable, it can be put to use in extracting the components of ODD variables, by EQUIVALENCEing it to a variable declared of type ODD. This is even possible if XYZ contains STRING or MUTABLE components, since the result of an EQUIVALENCE involving such items is to cause their static pointer parts to be within both variables, and therefore the dynamic parts of a variable of type ODD could be accessed through XYZ; this is one of the few useful applications of EQUIVALENCE for MUTABLE and STRING entities. As is implicit from the above, assignment between a variable and an expression of the same new type is automatically defined to follow the same rules as assignment for the entity describing its storage pattern.
No other operations on variables of new types, nor any conversions between the new type and any other types, are defined as a result of the MAKE statement; all such operations must be defined by the use of the ALIAS statement.
To define type conversions, it is necessary to use the ALIAS statement with the standard function _(typename,expression). This will define the standard manner for converting between a user-defined type and other types, and it will also be used where implicit type conversion is called for.
The name of a user-defined type (such as ODD in the example above) may be the same as that of a variable without causing confusion. User-defined type names can only pre-empt names of pre-existing types and typelike attributes (NEW, GLOBAL, EXTERNAL, MATHEMATICAL, TEXT, LIST_EQUATE, AUTO, and so on), if also used in a RESERVE statement, and in that case care must be taken.
In the normal mode of the YAL compiler, no type checking is performed during actual parameter passing; if conversion to the correct type is to be done for an argument, that argument position in the calling sequence is to be declared to be of the desired type in the calling program, but it is the programmer's responsibility to ensure that the requested type is in fact the correct type also declared in the called program. Thus, the issue of structural versus name equivalence for types defined in different modules does not arise.
Refer to the description of the ENVIRONMENT and ALIAS statements for further details concerning the use of variables of new types.