Revised November 2014
Parameters in function and procedure definitions have an optional "as <typsiz>{:<mod>)" clause to declare the type, size, and modifiers for the parameter. This also applies to the return type of the Function. If no clause is specified, the default type and size follows the normal rules for BASIC. The fact that you probably aren't 100% certain what those rules are should reinforce the importance of always defining the type and size explicitly. The following examples will help clarify the syntax:
Example 1
FUNCTION Fn'Test(p1 as S10, p2 as f6, p3 as B2, p4 As x256) AS i2
This illustrates the fact that although the <typsiz> clause uses the same fundamental data types as in MAP statements, here there is no comma between the type and size (e.g. "var2 as f6" instead of "map2 var2,f,6"). It also illustrates the the case insensitivity of the native type codes (F, S, B, X, I) and the "AS" keyword.
Example 2
Function fn'display'name$(cus as ST_CUS_REC, bold as BOOLEAN) as s MAX_NAME
This shows the possibility of using symbolic types and sizes rather than just the fundamental types and hard-coded sizes. One possibility is to use a defined structure (i.e. "as ST_CUS_REC"). See Defined Structures. Another is to use a symbol defined via a deftype statement (i.e. "bold as BOOLEAN"). Syntactically, it's impossible to tell the difference between a defined structure name and deftype name, but the assumption here is that BOOLEAN was defined via DEFTYPE BOOLEAN = I,2.
A third possibility is to replace just the size with a symbol, e.g. "as s MAX_NAME"). In this case, a single space is required between the native variable type ("s") and the symbol name ("MAX_NAME"). Using a symbol rather than a hard-coded number is useful for avoiding a common bug that may happen when passing string arguments to functions, where you decide to increase the size of the string field elsewhere in the application but forget about the function, resulting in the value being truncated within the function. But the technique has largely been superseded by the DEFTYPE method, which eliminates such discrepancies both in the parameter size and its type.
For string and X parameters, another way to avoid the truncation bug just described is to use Dynamically-Sized Variables within the function.
Example 3
function fn'test(p1 as s20:inputonly, p2 as ST_PHONE:outputonly)
This illustrates the use of the optional :<mod> clause to specify a modifier affecting the way the parameter is to be used. Currently the available modifiers are inputonly and outputonly.
The inputonly modifiier serves primarily as an aid to self-documenting code, but will also cause the compiler to generate an error if you explicitly reference the parameter in an XPUTARG statement using a literal parameter number. There is no run-time aspect of this feature, so you won't be stopped from outputting to the parameter using a variable to specify the parameter number in the XPUTARG statement.
The outputonly modifier also aids in self-documenting your code, but in addition it skips the input parameter binding operation (which, for very large parameters could save a lot of CPU cycles).
In the absence of an inputonly or outputonly modifier, the parameter is consider input/output. Note however, that since parameter passing is, in almost all cases, by value (as opposed to by reference), there is no automatic updating of the variables passed by the caller, unless you use explicit XPUTARG statements.
History
2009 April, A-Shell 5.1.1145: Feature added to A-Shell