FALCON supports tagged variables with changeable type as the type MUTABLE. Values of any other type can be assigned to a MUTABLE variable, which contains a flag saying, in effect, 'I contain a 30-character string', or 'I contain a 3 by 5 array of real numbers'.
Since FALCON also supports non-tagged data, for compatibility with older languages such as FORTRAN, and to allow skilled programmers to generate more efficient code, one consequence is that MUTABLE variables cannot have a tag saying 'I am a MUTABLE variable', since any such tag would be mistaken for data by a program expecting a non-tagged variable.
While it is possible for execution time conversion to MUTABLE form of variables to be very efficient (allow the pointer to point into regular variable storage as well as the MUTABLE/STRING storage pool: this is in fact required to implement _MQ(...), as well), it might still be preferred to avoid such an action, since the forms of operators and functions that act on MUTABLE variables all test, at execution time, for variable type.
This would require writing one version of a function desired to operate on variables of different types for each type desired, including MUTABLE. In the other versions, recourse to the ALIAS statement would be needed to create a dummy argument in which the dimensions of any arguments that could be arrays would be specified.
It is assumed by FALCON that undeclared external subprograms are set up to accept the arguments which they are given; note that expressions in FALCON only have MUTABLE type where they contain MUTABLE variables, or are created with _MQ, _AM, or &DIM (as in J &DIM 7, an array of sevens whose length is determined at execution time) or operators having similar effects. In addition to using the XSUB, XFUN, XOPR and XLFN statements, the MO (MUTABLE_ONLY) statement can declare subprograms all of whose arguments are to be MUTABLE, and the MN (MUTABLE_NEVER) statement can declare subprograms none of whose arguments are MUTABLE: the address of the data part of a MUTABLE variable or expression is passed, type and dimension information not being passed. FORTRAN subroutines should, at least, be declared MN if nothing else.
To avoid physically recopying an array when the &TSP function is performed, many implementations will include the order of dimensions in the current type of a MUTABLE variable: a vector giving this order for the variable v can be found from the function _CDO(v). Otherwise, the data part of a MUTABLE variable which is not an array of MUTABLE values should resemble a data type with a counterpart in FORTRAN; however, documentation at your installation should be consulted to ensure special coding is not used for sparse, diagonal, or symmetric matrices, for example.
Note that constants appearing in subprogram argument lists are always treated as expressions; their addresses are never passed; instead, where all arguments are passed internally by addresses, their values are copied into temporary storage, and the address of that storage passed. In some versions of FORTRAN, it is possible to alter the actual value of a constant by accident. Also, if the same variable is named twice in an argument list, all occurences of that variable as an argument are treated as expressions.
The Guard statement (GUARDED)
The GUARD statement
where FUN is a function instructs the compiler to protect FUN from array arguments: that is, in a program containing the statements
DIM A(3),B(3) GUARD FUN
becomes, in effect, replaced by
7 FOR I=1,3 . X(I)=FUN(A(I),B(I)) REPEAT 7
except, of course, that neither I nor the line number 7 is used.
Thus, a function FUN, not equipped to handle arguments other than scalars, is caused to behave like the primitive functions and operators of FALCON.
Operators may also be declared GUARDed by this statement, of course, and so can subroutines.
Multiple copies of the routine being GUARDed may be executed on parallel processors; note that variables declared STATIC but not UNIQUE are duplicated when the routine containing them is duplicated, so they act like AUTO variables in this case, but without the overhead.