FUNCTIONMACRO Structure

[resulttype] funcname ( parameterlist ) := FUNCTIONMACRO

code

RETURN retval;

ENDMACRO;

resulttypeThe return value type of the function. If omitted, the type is implicit from the retval expression.
funcname

The ECL definition name of the function/macro.

parameterlistA comma separated list of names (tokens) of the parameters that will be passed to the function/macro. These names are used in the code and retval to indicate where the passed parameter values are substituted when the function/macro is used. Value types for these parameters are not allowed, but default values may be specified as string constants.
codeThe local definitions that comprise the function. These may not be EXPORT or SHARED, but may include actions (like OUTPUT).
RETURNSpecifies the return value expression--the retval.
retvalThe value, expression, recordset, row (record), or action to return.

The FUNCTIONMACRO structure is a code generation tool, like the MACRO structure, coupled with the code encapsulation benefits of the FUNCTION structure. One advantage the FUNCTIONMACRO has over the MACRO structure is that it may be called in an expression context, just like a FUNCTION would be.

Unlike the MACRO structure, #UNIQUENAME is not necessary to prevent internal definition name clashes when the FUNCTIONMACRO is used multiple times within the same visibility scope. However, the LOCAL keyword must be explicitly used within the FUNCTIONMACRO if a definition name in its code may also have been defined outside the FUNCTIONMACRO and within the same visibility scope -- LOCAL clearly identifies that the definition is limited to the code within the FUNCTIONMACRO.

Example:

This example demonstrates the FUNCTIONMACRO used in an expression context. It also shows how the FUNCTIONMACRO may be called multiple times without name clashes from its internal definitions:

EXPORT Field_Population(infile,infield,compareval) := FUNCTIONMACRO
  c1 := COUNT(infile(infield=compareval));
  c2 := COUNT(infile);
  RETURN DATASET([{'Total Records',c2},
                  {'Recs=' + #TEXT(compareval),c1},
                  {'Population Pct',(INTEGER)(((c2-c1)/c2)* 100.0)}],
                 {STRING15 valuetype,INTEGER val});
ENDMACRO;

ds1 := dataset([{'M'},{'M'},{'M'},{''},{''},{'M'},{''},{'M'},{'M'},{''}],{STRING1 Gender});
ds2 := dataset([{''},{'M'},{'M'},{''},{''},{'M'},{''},{''},{'M'},{''}],{STRING1 Gender});

OUTPUT(Field_Population(ds1,Gender,''));
OUTPUT(Field_Population(ds2,Gender,''));

This example demonstrates use of the LOCAL keyword to prevent name clashes with external definitions within the same visibility scope as the FUNCTIONMACRO:

numPlus := 'this creates a syntax error without LOCAL in the FUNCTIONMACRO';
AddOne(num) := FUNCTIONMACRO
  LOCAL numPlus := num + 1;   //LOCAL required here
  RETURN numPlus;
ENDMACRO;

AddTwo(num) := FUNCTIONMACRO
  LOCAL numPlus := num + 2;   //LOCAL required here
  RETURN numPlus;
ENDMACRO;

numPlus;
AddOne(5);
AddTwo(8);

See Also: FUNCTION Structure, MACRO Structure