Function Definitions
Functions
(Parameter Passing
Parameter Passing
)
All of the basic Definition types can also become functions by
defining them to accept passed parameters (arguments
arguments
). The fact that it receives parameters doesn't change the
essential nature of the Definition's type, it simply makes it more
flexible.
Parameter definitions always appear in parentheses attached to the
Definition's name. You may define the function to receive as many parameters
as needed to create the desired functionality by simply separating each
succeeding parameter definition with a comma.
The format of parameter definitions is as follows:
DefinitionName( [
ValueType ]
AliasName [
=DefaultValue ] ) :=
expression;
ValueType
Optional. Specifies the type of data being passed. If
omitted, the default is INTEGER (see Value
Types
Value Types
). This also may include the CONST keyword
(see CONST
CONST
) to indicate that the passed value will
always be treated as a constant.
AliasName
Names the parameter for use in the expression.
DefaultValue
Optional. Provides the value to use in the expression if the
parameter is omitted. The DefaultValue may be
the keyword ALL if the ValueType is SET (see the SET
SET
keyword) to indicate all possible values
for that type of set, or empty square brackets
square brackets
([ ]) to indicate no possible value for that type of
set.
expression
The function's operation for which the parameters are
used.
Simple Value Type Parameters
If the optional ValueType is any of the simple
types (BOOLEAN, INTEGER, REAL, DECIMAL, STRING, QSTRING, UNICODE, DATA,
VARSTRING, VARUNICODE), the ValueType may include the
CONST keyword (see CONST) to indicate
that the passed value will always be treated as a constant (typically used
only in ECL prototypes of external functions).
ValueDefinition := 15;
FirstFunction(INTEGER x=5) := x + 5;
//takes an integer parameter named "x" and "x" is used in the
//arithmetic expression to indicate the usage of the parameter
SecondDefinition := FirstFunction(ValueDefinition);
// The value of SecondDefinition is 20
ThirdDefinition := FirstFunction();
// The value of ThirdDefinition is 10, omitting the parameter
SET Parameters
The DefaultValue for SET parameters
SET parameters
may be a default set of values, the keyword ALL to indicate
all possible values for that type of set, or empty square brackets ([ ])
to indicate no possible value for that type of set (and empty set).
SET OF INTEGER1 SetValues := [5,10,15,20];
IsInSetFunction(SET OF INTEGER1 x=SetValues,y) := y IN x;
OUTPUT(IsInSetFunction([1,2,3,4],5)); //false
OUTPUT(IsInSetFunction(,5)); // true
Passing DATASET Parameters
Passing a DATASET or a derived recordset as a parameter may be
accomplished using the following syntax:
DefinitionName(
DATASET
DATASET parameter
( recstruct ) AliasName ) := expression;
The required recstruct names the RECORD
structure that defines the layout of fields in the passed DATASET
parameter. The recstruct may alternatively use the
RECORDOF function. The required AliasName names the
dataset for use in the function and is used in the Definition's
expression to indicate where in the operation the
passed parameter is to be used. See the DATASET as a
Value Type discussion in the DATASET documentation for further
examples.
MyRec := {STRING1 Letter};
SomeFile := DATASET([{'A'},{'B'},{'C'},{'D'},{'E'}],MyRec);
FilteredDS(DATASET(MyRec) ds) := ds(Letter NOT IN ['A','C','E']);
//passed dataset referenced as “ds” in expression
OUTPUT(FilteredDS(SomeFile));
Passing DICTIONARY Parameters
Passing a DICTIONARY as a parameter may be accomplished using the
following syntax:
DefinitionName(
DICTIONARY
DICTIONARY parameter
( structure ) AliasName ) := expression;
The required structure parameter is the RECORD
structure that defines the layout of fields in the passed DICTIONARY
parameter (usually defined inline). The required
AliasName names the DICTIONARY for use in the function and is
used in the Definition's expression to indicate where
in the operation the passed parameter is to be used. See the DICTIONARY as a Value Type discussion in the
DICTIONARY documentation.
rec := RECORD
STRING10 color;
UNSIGNED1 code;
STRING10 name;
END;
Ds := DATASET([{'Black' ,0 , 'Fred'},
{'Brown' ,1 , 'Seth'},
{'Red' ,2 , 'Sue'},
{'White' ,3 , 'Jo'}], rec);
DsDCT := DICTIONARY(DS,{color => DS});
DCTrec := RECORD
STRING10 color =>
UNSIGNED1 code,
STRING10 name,
END;
InlineDCT := DICTIONARY([{'Black' => 0 , 'Fred'},
{'Brown' => 1 , 'Sam'},
{'Red' => 2 , 'Sue'},
{'White' => 3 , 'Jo'} ],
DCTrec);
MyDCTfunc(DICTIONARY(DCTrec) DCT,STRING10 key) := DCT[key].name;
MyDCTfunc(InlineDCT,'White'); //Jo
MyDCTfunc(DsDCT,'Brown'); //Seth
Passing Typeless Parameters
Passing parameters of any type may be accomplished using the keyword
ANY
ANY
as the passed value type:
DefinitionName (
ANY AliasName ) :=
expression;
a := 10;
b := 20;
c := '1';
d := '2';
e := '3';
f := '4';
s1 := [c,d];
s2 := [e,f];
ds1 := DATASET(s1,{STRING1 ltr});
ds2 := DATASET(s2,{STRING1 ltr});
MyFunc(ANY l, ANY r) := l + r;
MyFunc(a,b); //returns 30
MyFunc(a,c); //returns '101'
MyFunc(c,d); //returns '12'
MyFunc(s1,s2); //returns a set: ['1','2','3','4']
MyFunc(ds1,ds2); //returns 4 records: '1', '2', '3', and '4'
Passing Function Parameters
Passing a Function as a parameter may be accomplished using either
of the following syntax options as the ValueType for
the parameter:
FunctionName(parameters)
PrototypeName
FunctionName
The name of a function, the type of which may be passed as
a parameter.
parameters
The parameter definitions for the
FunctionName parameter.
PrototypeName
The name of a previously defined function to use as the
type of function that may be passed as a parameter.
The following code provides examples of both methods:
//a Function prototype:
INTEGER actionPrototype(INTEGER v1, INTEGER v2) := 0;
INTEGER aveValues(INTEGER v1, INTEGER v2) := (v1 + v2) DIV 2;
INTEGER addValues(INTEGER v1, INTEGER v2) := v1 + v2;
INTEGER multiValues(INTEGER v1, INTEGER v2) := v1 * v2;
//a Function prototype using a function prototype:
INTEGER applyPrototype(INTEGER v1, actionPrototype actionFunc) := 0;
//using the Function prototype and a default value:
INTEGER applyValue2(INTEGER v1,
actionPrototype actionFunc = aveValues) :=
actionFunc(v1, v1+1)*2;
//Defining the Function parameter inline, witha default value:
INTEGER applyValue4(INTEGER v1,
INTEGER actionFunc(INTEGER v1,INTEGER v2) = aveValues)
:= actionFunc(v1, v1+1)*4;
INTEGER doApplyValue(INTEGER v1,
INTEGER actionFunc(INTEGER v1, INTEGER v2))
:= applyValue2(v1+1, actionFunc);
//producing simple results:
OUTPUT(applyValue2(1)); // 2
OUTPUT(applyValue2(2)); // 4
OUTPUT(applyValue2(1, addValues)); // 6
OUTPUT(applyValue2(2, addValues)); // 10
OUTPUT(applyValue2(1, multiValues)); // 4
OUTPUT(applyValue2(2, multiValues)); // 12
OUTPUT(doApplyValue(1, multiValues)); // 12
OUTPUT(doApplyValue(2, multiValues)); // 24
//A definition taking function parameters which themselves
//have parameters that are functions...
STRING doMany(INTEGER v1,
INTEGER firstAction(INTEGER v1,
INTEGER actionFunc(INTEGER v1,INTEGER v2)),
INTEGER secondAction(INTEGER v1,
INTEGER actionFunc(INTEGER v1,INTEGER v2)),
INTEGER actionFunc(INTEGER v1,INTEGER v2))
:= (STRING)firstAction(v1, actionFunc) + ':' + (STRING)secondaction(v1, actionFunc);
OUTPUT(doMany(1, applyValue2, applyValue4, addValues));
// produces "6:12"
OUTPUT(doMany(2, applyValue4, applyValue2,multiValues));
// produces "24:12"
Passing NAMED Parameters
Passing values to a function defined to receive multiple parameters,
many of which have default values (and are therefore omittable), is
usually accomplished by “counting commas” to ensure that the values you
choose to pass are passed to the correct parameter by the parameter's
position in the list. This method becomes untenable when there are many
optional parameters.
The easier method is to use the following NAMED parameter syntax,
which eliminates the need to include extraneous commas as place holders to
put the passed values in the proper parameters:
Attr := FunctionName( [ NAMED
NAMED
] AliasName := value );
NAMED
Optional. Required only when the AliasName
clashes with a reserved word.
AliasName
The names of the parameter in the definition's function
definition.
value
The value to pass to the parameter.
This syntax is used in the call to the function and allows you to
pass values to specific parameters by their
AliasName, without regard for their position in the
list. All unnamed parameters passed must precede any NAMED
parameters.
outputRow(BOOLEAN showA = FALSE, BOOLEAN showB = FALSE,
BOOLEAN showC = FALSE, STRING aValue = 'abc',
INTEGER bValue = 10, BOOLEAN cValue = TRUE) :=
OUTPUT(IF(showA,' a='+aValue,'')+
IF(showB,' b='+(STRING)bValue,'')+
IF(showc,' c='+(STRING)cValue,''));
outputRow(); //produce blanks
outputRow(TRUE); //produce "a=abc"
outputRow(,,TRUE); //produce "c=TRUE"
outputRow(NAMED showB := TRUE); //produce “b=10”
outputRow(TRUE, NAMED aValue := 'Changed value');
//produce “a=Changed value”
outputRow(,,,'Changed value2',NAMED showA := TRUE);
//produce "a=Changed value2"
outputRow(showB := TRUE); //produce “b=10”
outputRow(TRUE, aValue := 'Changed value');
outputRow(,,,'Changed value2',showA := TRUE);