Basics-FunctionAttributes.xml 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE sect1 PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
  3. "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
  4. <sect1 id="Function_Attributes__Parameter_Passing">
  5. <title>Function Definitions<indexterm>
  6. <primary>Functions</primary>
  7. </indexterm> (Parameter Passing<indexterm>
  8. <primary><emphasis role="bold">Parameter Passing</emphasis></primary>
  9. </indexterm>)</title>
  10. <para>All of the basic Definition types can also become functions by
  11. defining them to accept passed parameters (arguments<indexterm>
  12. <primary>arguments</primary>
  13. </indexterm>). The fact that it receives parameters doesn't change the
  14. essential nature of the Definition's type, it simply makes it more
  15. flexible.</para>
  16. <para>Parameter definitions always appear in parentheses attached to the
  17. Definition's name. You may define the function to receive as many parameters
  18. as needed to create the desired functionality by simply separating each
  19. succeeding parameter definition with a comma.</para>
  20. <para>The format of parameter definitions is as follows:</para>
  21. <para>DefinitionName<emphasis role="bold">( [
  22. </emphasis><emphasis>ValueType</emphasis><emphasis role="bold"> ]
  23. </emphasis><emphasis>AliasName</emphasis><emphasis role="bold"> [
  24. =</emphasis><emphasis>DefaultValue</emphasis><emphasis role="bold"> ] ) :=
  25. </emphasis>expression<emphasis role="bold">;</emphasis></para>
  26. <informaltable colsep="1" frame="all" rowsep="1">
  27. <tgroup cols="2">
  28. <colspec align="left" colwidth="122.40pt" />
  29. <colspec />
  30. <tbody>
  31. <row>
  32. <entry><emphasis>ValueType</emphasis></entry>
  33. <entry>Optional. Specifies the type of data being passed. If
  34. omitted, the default is INTEGER (see <emphasis role="bold">Value
  35. Types<indexterm>
  36. <primary><emphasis role="bold">Value Types</emphasis></primary>
  37. </indexterm></emphasis>). This also may include the CONST keyword
  38. (see <emphasis role="bold">CONST<indexterm>
  39. <primary>CONST</primary>
  40. </indexterm></emphasis>) to indicate that the passed value will
  41. always be treated as a constant.</entry>
  42. </row>
  43. <row>
  44. <entry><emphasis>AliasName</emphasis></entry>
  45. <entry>Names the parameter for use in the expression.</entry>
  46. </row>
  47. <row>
  48. <entry><emphasis>DefaultValue</emphasis></entry>
  49. <entry>Optional. Provides the value to use in the expression if the
  50. parameter is omitted. The <emphasis>DefaultValue</emphasis> may be
  51. the keyword ALL if the ValueType is SET (see the <emphasis
  52. role="bold">SET<indexterm>
  53. <primary>SET</primary>
  54. </indexterm></emphasis> keyword) to indicate all possible values
  55. for that type of set, or empty square brackets<indexterm>
  56. <primary>square brackets</primary>
  57. </indexterm> ([ ]) to indicate no possible value for that type of
  58. set.</entry>
  59. </row>
  60. <row>
  61. <entry><emphasis>expression</emphasis></entry>
  62. <entry>The function's operation for which the parameters are
  63. used.</entry>
  64. </row>
  65. </tbody>
  66. </tgroup>
  67. </informaltable>
  68. <sect2 id="Simple_Value_Type_Parameters">
  69. <title>Simple Value Type Parameters</title>
  70. <para>If the optional <emphasis>ValueType</emphasis> is any of the simple
  71. types (BOOLEAN, INTEGER, REAL, DECIMAL, STRING, QSTRING, UNICODE, DATA,
  72. VARSTRING, VARUNICODE), the <emphasis>ValueType</emphasis> may include the
  73. CONST keyword (see <emphasis role="bold">CONST</emphasis>) to indicate
  74. that the passed value will always be treated as a constant (typically used
  75. only in ECL prototypes of external functions).</para>
  76. <programlisting>ValueDefinition := 15;
  77. FirstFunction(INTEGER x=5) := x + 5;
  78. //takes an integer parameter named "x" and "x" is used in the
  79. //arithmetic expression to indicate the usage of the parameter
  80. SecondDefinition := FirstFunction(ValueDefinition);
  81. // The value of SecondDefinition is 20
  82. ThirdDefinition := FirstFunction();
  83. // The value of ThirdDefinition is 10, omitting the parameter</programlisting>
  84. </sect2>
  85. <sect2 id="SET_Parameters">
  86. <title>SET Parameters</title>
  87. <para>The <emphasis>DefaultValue</emphasis> for SET parameters<indexterm>
  88. <primary>SET parameters</primary>
  89. </indexterm> may be a default set of values, the keyword ALL to indicate
  90. all possible values for that type of set, or empty square brackets ([ ])
  91. to indicate no possible value for that type of set (and empty set).</para>
  92. <programlisting>SET OF INTEGER1 SetValues := [5,10,15,20];
  93. IsInSetFunction(SET OF INTEGER1 x=SetValues,y) := y IN x;
  94. OUTPUT(IsInSetFunction([1,2,3,4],5)); //false
  95. OUTPUT(IsInSetFunction(,5)); // true</programlisting>
  96. </sect2>
  97. <sect2 id="Passing_DATASET_Parameters">
  98. <title>Passing DATASET Parameters</title>
  99. <para>Passing a DATASET or a derived recordset as a parameter may be
  100. accomplished using the following syntax:</para>
  101. <para><emphasis>DefinitionName</emphasis><emphasis role="bold">(
  102. DATASET<indexterm>
  103. <primary>DATASET parameter</primary>
  104. </indexterm>(</emphasis><emphasis> recstruct </emphasis><emphasis
  105. role="bold">) </emphasis><emphasis>AliasName</emphasis><emphasis
  106. role="bold"> ) := </emphasis><emphasis>expression</emphasis><emphasis
  107. role="bold">;</emphasis></para>
  108. <para>The required<emphasis> recstruct</emphasis> names the RECORD
  109. structure that defines the layout of fields in the passed DATASET
  110. parameter. The <emphasis>recstruct</emphasis> may alternatively use the
  111. RECORDOF function. The required<emphasis> AliasName</emphasis> names the
  112. dataset for use in the function and is used in the Definition's
  113. <emphasis>expression</emphasis> to indicate where in the operation the
  114. passed parameter is to be used. See the <emphasis role="bold">DATASET as a
  115. Value Type</emphasis> discussion in the DATASET documentation for further
  116. examples.</para>
  117. <programlisting>MyRec := {STRING1 Letter};
  118. SomeFile := DATASET([{'A'},{'B'},{'C'},{'D'},{'E'}],MyRec);
  119. FilteredDS(DATASET(MyRec) ds) := ds(Letter NOT IN ['A','C','E']);
  120. //passed dataset referenced as “ds” in expression
  121. OUTPUT(FilteredDS(SomeFile));</programlisting>
  122. </sect2>
  123. <sect2 id="Passing_DICTIONARY_Parameters">
  124. <title>Passing DICTIONARY Parameters</title>
  125. <para>Passing a DICTIONARY as a parameter may be accomplished using the
  126. following syntax:</para>
  127. <para><emphasis>DefinitionName</emphasis><emphasis role="bold">(
  128. DICTIONARY<indexterm>
  129. <primary>DICTIONARY parameter</primary>
  130. </indexterm>(</emphasis><emphasis> structure </emphasis><emphasis
  131. role="bold">) </emphasis><emphasis>AliasName</emphasis><emphasis
  132. role="bold"> ) := </emphasis><emphasis>expression</emphasis><emphasis
  133. role="bold">;</emphasis></para>
  134. <para>The required <emphasis>structure</emphasis> parameter is the RECORD
  135. structure that defines the layout of fields in the passed DICTIONARY
  136. parameter (usually defined inline). The required<emphasis>
  137. AliasName</emphasis> names the DICTIONARY for use in the function and is
  138. used in the Definition's <emphasis>expression</emphasis> to indicate where
  139. in the operation the passed parameter is to be used. See the <emphasis
  140. role="bold">DICTIONARY as a Value Type</emphasis> discussion in the
  141. DICTIONARY documentation.</para>
  142. <programlisting>rec := RECORD
  143. STRING10 color;
  144. UNSIGNED1 code;
  145. STRING10 name;
  146. END;
  147. Ds := DATASET([{'Black' ,0 , 'Fred'},
  148. {'Brown' ,1 , 'Seth'},
  149. {'Red' ,2 , 'Sue'},
  150. {'White' ,3 , 'Jo'}], rec);
  151. DsDCT := DICTIONARY(DS,{color =&gt; DS});
  152. DCTrec := RECORD
  153. STRING10 color =&gt;
  154. UNSIGNED1 code,
  155. STRING10 name,
  156. END;
  157. InlineDCT := DICTIONARY([{'Black' =&gt; 0 , 'Fred'},
  158. {'Brown' =&gt; 1 , 'Sam'},
  159. {'Red' =&gt; 2 , 'Sue'},
  160. {'White' =&gt; 3 , 'Jo'} ],
  161. DCTrec);
  162. MyDCTfunc(DICTIONARY(DCTrec) DCT,STRING10 key) := DCT[key].name;
  163. MyDCTfunc(InlineDCT,'White'); //Jo
  164. MyDCTfunc(DsDCT,'Brown'); //Seth</programlisting>
  165. </sect2>
  166. <sect2 id="Passing_Typeless_Parameters">
  167. <title>Passing Typeless Parameters</title>
  168. <para>Passing parameters of any type may be accomplished using the keyword
  169. ANY<indexterm>
  170. <primary>ANY</primary>
  171. </indexterm> as the passed value type:</para>
  172. <para><emphasis>DefinitionName</emphasis> <emphasis role="bold">(
  173. ANY</emphasis> <emphasis>AliasName</emphasis> <emphasis role="bold"> ) :=
  174. </emphasis><emphasis>expression</emphasis><emphasis
  175. role="bold">;</emphasis></para>
  176. <programlisting>a := 10;
  177. b := 20;
  178. c := '1';
  179. d := '2';
  180. e := '3';
  181. f := '4';
  182. s1 := [c,d];
  183. s2 := [e,f];
  184. ds1 := DATASET(s1,{STRING1 ltr});
  185. ds2 := DATASET(s2,{STRING1 ltr});
  186. MyFunc(ANY l, ANY r) := l + r;
  187. MyFunc(a,b); //returns 30
  188. MyFunc(a,c); //returns '101'
  189. MyFunc(c,d); //returns '12'
  190. MyFunc(s1,s2); //returns a set: ['1','2','3','4']
  191. MyFunc(ds1,ds2); //returns 4 records: '1', '2', '3', and '4'
  192. </programlisting>
  193. </sect2>
  194. <sect2 id="Passing_Function_Parameters">
  195. <title>Passing Function Parameters</title>
  196. <para>Passing a Function as a parameter may be accomplished using either
  197. of the following syntax options as the <emphasis>ValueType</emphasis> for
  198. the parameter:</para>
  199. <para><emphasis>FunctionName</emphasis>(<emphasis
  200. role="bold"></emphasis><emphasis>parameters</emphasis><emphasis
  201. role="bold"></emphasis>)<emphasis></emphasis></para>
  202. <para><emphasis>PrototypeName</emphasis></para>
  203. <informaltable colsep="1" frame="all" rowsep="1">
  204. <tgroup cols="2">
  205. <colspec align="left" colwidth="122.40pt" />
  206. <colspec />
  207. <tbody>
  208. <row>
  209. <entry><emphasis>FunctionName</emphasis></entry>
  210. <entry>The name of a function, the type of which may be passed as
  211. a parameter.</entry>
  212. </row>
  213. <row>
  214. <entry><emphasis>parameters</emphasis></entry>
  215. <entry>The parameter definitions for the
  216. <emphasis>FunctionName</emphasis> parameter.</entry>
  217. </row>
  218. <row>
  219. <entry><emphasis>PrototypeName</emphasis></entry>
  220. <entry>The name of a previously defined function to use as the
  221. type of function that may be passed as a parameter.</entry>
  222. </row>
  223. </tbody>
  224. </tgroup>
  225. </informaltable>
  226. <para>The following code provides examples of both methods:</para>
  227. <programlisting>//a Function prototype:
  228. INTEGER actionPrototype(INTEGER v1, INTEGER v2) := 0;
  229. INTEGER aveValues(INTEGER v1, INTEGER v2) := (v1 + v2) DIV 2;
  230. INTEGER addValues(INTEGER v1, INTEGER v2) := v1 + v2;
  231. INTEGER multiValues(INTEGER v1, INTEGER v2) := v1 * v2;
  232. //a Function prototype using a function prototype:
  233. INTEGER applyPrototype(INTEGER v1, actionPrototype actionFunc) := 0;
  234. //using the Function prototype and a default value:
  235. INTEGER applyValue2(INTEGER v1,
  236. actionPrototype actionFunc = aveValues) :=
  237. actionFunc(v1, v1+1)*2;
  238. //Defining the Function parameter inline, witha default value:
  239. INTEGER applyValue4(INTEGER v1,
  240. INTEGER actionFunc(INTEGER v1,INTEGER v2) = aveValues)
  241. := actionFunc(v1, v1+1)*4;
  242. INTEGER doApplyValue(INTEGER v1,
  243. INTEGER actionFunc(INTEGER v1, INTEGER v2))
  244. := applyValue2(v1+1, actionFunc);
  245. //producing simple results:
  246. OUTPUT(applyValue2(1)); // 2
  247. OUTPUT(applyValue2(2)); // 4
  248. OUTPUT(applyValue2(1, addValues)); // 6
  249. OUTPUT(applyValue2(2, addValues)); // 10
  250. OUTPUT(applyValue2(1, multiValues)); // 4
  251. OUTPUT(applyValue2(2, multiValues)); // 12
  252. OUTPUT(doApplyValue(1, multiValues)); // 12
  253. OUTPUT(doApplyValue(2, multiValues)); // 24
  254. //A definition taking function parameters which themselves
  255. //have parameters that are functions...
  256. STRING doMany(INTEGER v1,
  257. INTEGER firstAction(INTEGER v1,
  258. INTEGER actionFunc(INTEGER v1,INTEGER v2)),
  259. INTEGER secondAction(INTEGER v1,
  260. INTEGER actionFunc(INTEGER v1,INTEGER v2)),
  261. INTEGER actionFunc(INTEGER v1,INTEGER v2))
  262. := (STRING)firstAction(v1, actionFunc) + ':' + (STRING)secondaction(v1, actionFunc);
  263. OUTPUT(doMany(1, applyValue2, applyValue4, addValues));
  264. // produces "6:12"
  265. OUTPUT(doMany(2, applyValue4, applyValue2,multiValues));
  266. // produces "24:12" </programlisting>
  267. </sect2>
  268. <sect2 id="Passing_NAMED_Parameters">
  269. <title>Passing NAMED Parameters</title>
  270. <para>Passing values to a function defined to receive multiple parameters,
  271. many of which have default values (and are therefore omittable), is
  272. usually accomplished by “counting commas” to ensure that the values you
  273. choose to pass are passed to the correct parameter by the parameter's
  274. position in the list. This method becomes untenable when there are many
  275. optional parameters.</para>
  276. <para>The easier method is to use the following NAMED parameter syntax,
  277. which eliminates the need to include extraneous commas as place holders to
  278. put the passed values in the proper parameters:</para>
  279. <para>Attr := FunctionName<emphasis role="bold">( [ NAMED<indexterm>
  280. <primary>NAMED</primary>
  281. </indexterm> ] </emphasis><emphasis>AliasName</emphasis><emphasis
  282. role="bold"> := </emphasis><emphasis>value </emphasis><emphasis
  283. role="bold">);</emphasis></para>
  284. <informaltable colsep="1" frame="all" rowsep="1">
  285. <tgroup cols="2">
  286. <colspec align="left" colwidth="122.40pt" />
  287. <colspec />
  288. <tbody>
  289. <row>
  290. <entry><emphasis>NAMED</emphasis></entry>
  291. <entry>Optional. Required only when the <emphasis>AliasName
  292. </emphasis>clashes with a reserved word.</entry>
  293. </row>
  294. <row>
  295. <entry><emphasis>AliasName</emphasis></entry>
  296. <entry>The names of the parameter in the definition's function
  297. definition.</entry>
  298. </row>
  299. <row>
  300. <entry><emphasis>value</emphasis></entry>
  301. <entry>The value to pass to the parameter.</entry>
  302. </row>
  303. </tbody>
  304. </tgroup>
  305. </informaltable>
  306. <para>This syntax is used in the call to the function and allows you to
  307. pass values to specific parameters by their
  308. <emphasis>AliasName</emphasis>, without regard for their position in the
  309. list. All unnamed parameters passed must precede any NAMED
  310. parameters.</para>
  311. <programlisting>outputRow(BOOLEAN showA = FALSE, BOOLEAN showB = FALSE,
  312. BOOLEAN showC = FALSE, STRING aValue = 'abc',
  313. INTEGER bValue = 10, BOOLEAN cValue = TRUE) :=
  314. OUTPUT(IF(showA,' a='+aValue,'')+
  315. IF(showB,' b='+(STRING)bValue,'')+
  316. IF(showc,' c='+(STRING)cValue,''));
  317. outputRow(); //produce blanks
  318. outputRow(TRUE); //produce "a=abc"
  319. outputRow(,,TRUE); //produce "c=TRUE"
  320. outputRow(NAMED showB := TRUE); //produce “b=10”
  321. outputRow(TRUE, NAMED aValue := 'Changed value');
  322. //produce “a=Changed value”
  323. outputRow(,,,'Changed value2',NAMED showA := TRUE);
  324. //produce "a=Changed value2"
  325. outputRow(showB := TRUE); //produce “b=10”
  326. outputRow(TRUE, aValue := 'Changed value');
  327. outputRow(,,,'Changed value2',showA := TRUE);
  328. </programlisting>
  329. </sect2>
  330. </sect1>