home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 3 / TheARMClub_PDCD3.iso / hensa / maths / rlab / docs / RLEF43~1 < prev    next >
Encoding:
Text File  |  1997-02-10  |  17.6 KB  |  542 lines

  1. <HTML>
  2. <HEAD>
  3. <TITLE> Rlab2 Reference Manual: User Functions</TITLE>
  4. </HEAD>
  5. <BODY>
  6. <A HREF="rlab-ref-5.html"><IMG SRC="prev.gif" ALT="Previous"></A>
  7. <A HREF="rlab-ref-7.html"><IMG SRC="next.gif" ALT="Next"></A>
  8. <A HREF="rlab-ref.html#toc6"><IMG SRC="toc.gif" ALT="Contents"></A>
  9. <HR>
  10. <H2><A NAME="s6">6. User Functions</A></H2>
  11.  
  12.  
  13.  
  14. <P>Functions are almost first class variables in Rlab. Functions are
  15. stored as ordinary variables in the symbol-table; this explains the
  16. unusual syntax for creating and storing a function. User written
  17. functions are a key feature in any high level language. Mastering
  18. their usage is key to getting the most out of Rlab.</P>
  19. <P>User functions are created within the Rlab programming
  20. environment... that is the major distinction between user and
  21. builtin functions. Otherwise, there is no difference in the usage of
  22. builtin and user-written functions.</P>
  23. <P>The argument passing and function scoping rules are fairly
  24. straightforward and simple. The primary objective is ease of use,
  25. and safety, without compromising capability or efficiency.</P>
  26. <P>The two inter-related concepts important to understanding functions
  27. are <EM>execution-environments</EM>, and <EM>variable-scopes</EM>.  An
  28. <EM>execution-environment</EM> consists of the variables available to
  29. the currently executing statements. A variable's scope refers to the
  30. environment that variable is bound to. For instance statements
  31. executed from the command line are always executed in the
  32. global-environment. The global environment consists of all variables
  33. and functions created within that environment. Thus, a statement
  34. executed in the global environment only has access to global
  35. variables.</P>
  36. <P>All function arguments, and variables created within functions are
  37. visible only within the function's environment, or
  38. <EM>local-scope</EM>. Conversely, function statements do not have
  39. access to variables in the global-scope (unless certain steps are
  40. taken).</P>
  41. <P>Furthermore, function arguments can be considered local variables
  42. (in simplistic sense). Any modifications to a function's arguments
  43. are only visible within the function's environment. This is commonly
  44. referred to as "pass by value" (as opposed to "pass by
  45. reference"). Pass by value means that a variable's value (as opposed
  46. to the variable itself) is passed to the function's
  47. environment. Thus, when a function argument is modified, only a copy
  48. of its value is affected, and not the original variable.</P>
  49. <P>This separation of environments, or scopes, ensures a "safe"
  50. programming environment. Function writers will not accidentally
  51. clobber a global variable with a function statement, and users will
  52. not accidentally impair the operation of a function with global
  53. statements. </P>
  54.  
  55.  
  56. <H2><A NAME="ss6.1">6.1 Function Syntax</A></H2>
  57.  
  58.  
  59. <P>The function definition syntax is:</P>
  60. <P>
  61. <BLOCKQUOTE>
  62. function ( <EM>arg1</EM> , <EM>arg2</EM> , ... <EM>argN</EM> )
  63. {
  64. <EM>statements</EM>
  65. }
  66. </BLOCKQUOTE>
  67. </P>
  68. <P>Of course, the function must be assigned to a variable in order for
  69. it to be usable:</P>
  70. <P>
  71. <BLOCKQUOTE>
  72. <EM>var</EM> = function ( <EM>arg1</EM> , <EM>arg2</EM> , ... <EM>argN</EM> )
  73. {
  74. <EM>statements</EM>
  75. }
  76. </BLOCKQUOTE>
  77. </P>
  78. <P>The number of arguments, and their names are arbitrary (actually
  79. there is a 32 argument limit. If anyone ever hits that limit, it can
  80. be easily increased). The function can be used with fewer arguments
  81. than specified, but not more.</P>
  82. <P>The function <EM>statements</EM> are any valid Rlab statements, with
  83. the exception of other function definitions. The optional
  84. <EM>return-statement</EM> is peculiar to functions, and allows the
  85. program to return data to the calling environment.</P>
  86.  
  87.  
  88.  
  89. <H2><A NAME="ss6.2">6.2 Using Functions</A></H2>
  90.  
  91.  
  92. <P>Every invocation of a function returns a value. Normally the user
  93. determines the return-value of a function. However, if a return
  94. statement does not exist, the function return value will default to
  95. zero. Since function invocations are expressions, many syntactical
  96. shortcuts can be taken. For example, if a function returns a list,
  97. like the <CODE>eig</CODE> function:</P>
  98. <P>
  99. <BLOCKQUOTE><CODE>
  100. <PRE>
  101. > eig(a)
  102.    val          vec          
  103. > eig(a).val
  104.    -0.677      0.469       1.44  
  105. </PRE>
  106. </CODE></BLOCKQUOTE>
  107. </P>
  108. <P><CODE>eig</CODE> returns a list containing the elements <CODE>val</CODE> and
  109. <CODE>vec</CODE>; if we just want to get at one of the list elements, such
  110. as <CODE>val</CODE>, we can extract it directly. The same sort of shortcut
  111. can be used when a function returns matrices:</P>
  112. <P>
  113. <BLOCKQUOTE><CODE>
  114. <PRE>
  115. > size(rand(20,30))
  116.        20         30  
  117. > size(rand(20,30))[2]
  118.        30  
  119. </PRE>
  120. </CODE></BLOCKQUOTE>
  121. </P>
  122.  
  123.  
  124.  
  125.  
  126. <H2><A NAME="ss6.3">6.3 Function Arguments</A></H2>
  127.  
  128.  
  129. <P>As mentioned earlier, functions can have an arbitrary number of
  130. arguments. When program execution is passed to a user-function, all
  131. or some, or none of the arguments can be specified. Arguments that
  132. are not specified are replaced with UNDEFINED objects. How well the
  133. user-functions behaves when invoked with varying argument lists is
  134. entirely up to the user/programmer. If you don't want to specify the
  135. last N arguments to a function, just truncate the argument list. If
  136. you don't want to specify arguments that are in the beginning, or
  137. middle of the complete list of arguments, use commas. For example, a
  138. user-function defined like:</P>
  139. <P>
  140. <BLOCKQUOTE><CODE>
  141. <PRE>
  142. > x = function ( arg1 , arg2 , arg3 , arg4 )
  143.   {
  144.     if (exist (arg1)) { arg1 }
  145.     if (exist (arg2)) { arg2 }
  146.     if (exist (arg3)) { arg3 }
  147.     if (exist (arg4)) { arg4 }
  148.   }
  149.         <user-function>
  150. </PRE>
  151. </CODE></BLOCKQUOTE>
  152. </P>
  153. <P>Can be used as follows:</P>
  154. <P>
  155. <BLOCKQUOTE><CODE>
  156. <PRE>
  157. > x ( );
  158. > x ( pi );
  159.      3.14  
  160. > x ( pi, 2*pi );
  161.      3.14  
  162.      6.28  
  163. > x ( , , , 4*pi );
  164.      12.6  
  165. </PRE>
  166. </CODE></BLOCKQUOTE>
  167. </P>
  168. <P>In the first instance, no arguments are specified, and the function
  169. does nothing. In the second instance, only the first argument is
  170. specified, and it is echoed to the screen. In the third instance,
  171. the first and second arguments are specified, and are properly
  172. echoed. In the last case, only the fourth argument is specified.</P>
  173. <P>Each function has a local variable named <CODE>nargs</CODE>
  174. available. <CODE>nargs</CODE> is automatically set to the number of
  175. arguments passed to a function for each invocation. For example:</P>
  176. <P>
  177. <BLOCKQUOTE><CODE>
  178. <PRE>
  179. > x = function ( a, b, c, d, e, f, g ) { return nargs; }
  180.         <user-function>
  181. > x(1,2,3)
  182.         3
  183. > x(1,,2)
  184.         3
  185. </PRE>
  186. </CODE></BLOCKQUOTE>
  187. </P>
  188. <P>This simple one-line function demonstrates how the <CODE>nargs</CODE>
  189. variable is initialized. Notice that while nargs correctly reports
  190. the number of arguments in the first instance, the results from the
  191. second trial may seem a little confusing. The variable <CODE>nargs</CODE>
  192. is intended to provide programmers with the number of arguments
  193. passed to a user-function, and to provide some degree of
  194. compatibility with other popular very high-level languages. However,
  195. the existence of the variable <CODE>nargs</CODE> and the ability to
  196. <EM>skip</EM> arguments conflict and make the meaning of <CODE>nargs</CODE>
  197. ambiguous. The bottom line is: <CODE>nargs</CODE> has the value of the
  198. argument number of the last <EM>specified</EM> argument.</P>
  199. <P>A better method of determining which arguments were explicitly
  200. specified, and where were not is the use the builtin function
  201. <CODE>exist</CODE>. For example:</P>
  202. <P>
  203. <BLOCKQUOTE><CODE>
  204. <PRE>
  205. > x = function ( a , b, c, d, e, f, g )
  206.   {
  207.     if (exist (a)) { "1st argument was specified" }
  208.     if (!exist (a)) { "1st argument was not specified" }
  209.   }
  210.         <user-function>
  211. > x(2);
  212. 1st argument was specified  
  213. > x(,3);
  214. 1st argument was not specified  
  215. </PRE>
  216. </CODE></BLOCKQUOTE>
  217. </P>
  218. <P>This method is often used to decide if an argument's default value
  219. needs to be used. Another example:</P>
  220. <P>
  221. <BLOCKQUOTE><CODE>
  222. <PRE>
  223. > # compute a partial sum of a vector...
  224. > psum = function ( v , n )
  225.   {
  226.     if (!exist (n)) { n = length (v); }
  227.     return sum (v[1:n]);
  228.   }
  229.         <user-function>
  230. > v = rand(1024,1);
  231. > psum(v)
  232.       497  
  233. > psum(v,5)
  234.      2.99  
  235. </PRE>
  236. </CODE></BLOCKQUOTE>
  237. </P>
  238.  
  239.  
  240.  
  241. <H2><A NAME="ss6.4">6.4 Function Variable Scoping Rules</A></H2>
  242.  
  243.  
  244. <P>Although the subject of function variable scoping has already been
  245. addressed, it deserves more attention. Rlab utilizes a pass by value
  246. scheme for all function arguments. In many interpretive languages,
  247. this means a copy of the function arguments is made prior to
  248. function execution. This practice can be very time and memory
  249. inefficient, especially when large matrices or list-structures are
  250. function arguments. Rlab does <EM>not</EM> copy function arguments,
  251. unless the function modifies the arguments.</P>
  252. <P>
  253. <BLOCKQUOTE><CODE>
  254. <PRE>
  255. > x = function ( a ) { global(A) a = 2*a; A ? return a; }
  256.         <user-function>
  257. > A = 2*pi
  258.      6.28  
  259. > x(A)
  260.      6.28  
  261.      12.6  
  262. > A
  263.      6.28  
  264. </PRE>
  265. </CODE></BLOCKQUOTE>
  266. </P>
  267. <P>In the above example the function <CODE>x</CODE> modifies its argument
  268. <CODE>a</CODE>. Before modifying its argument, the function prints the
  269. value of the global variable <CODE>A</CODE>. <CODE>A</CODE> is assigned the
  270. value of <CODE>2*pi</CODE>, and <CODE>x</CODE> is called with argument
  271. <CODE>A</CODE>. After <CODE>x</CODE> modifies its argument, <CODE>A</CODE> is
  272. printed; note that the value of <CODE>A</CODE> is not changed. Printing
  273. the value of <CODE>A</CODE> afterwards verifies that its value has not
  274. changed. </P>
  275.  
  276.  
  277.  
  278. <H2><A NAME="ss6.5">6.5 Function Recursion</A></H2>
  279.  
  280.  
  281. <P>Functions can be used recursively. Each invocation of a function
  282. creates a unique environment. Probably the most popular example for
  283. displaying this type of behavior is the factorial function:</P>
  284. <P>
  285. <HR>
  286. <PRE>
  287. //
  288. // Fac.r (the slowest fac(), but the most interesting)
  289. //
  290.  
  291. fac = function(a) 
  292. {
  293.   if(a <= 1) 
  294.   {
  295.       return 1;
  296.   else
  297.       return a*$self(a-1);
  298.   }
  299. };
  300. </PRE>
  301. <HR>
  302. </P>
  303. <P>The special syntax: <CODE>$self</CODE> can be used within recursive
  304. functions to protect against the possibility of the function being
  305. renamed. </P>
  306. <P>
  307. <BLOCKQUOTE><CODE>
  308. <PRE>
  309. > fac(4)
  310.        24  
  311. </PRE>
  312. </CODE></BLOCKQUOTE>
  313. </P>
  314.  
  315.  
  316.  
  317. <H2><A NAME="ss6.6">6.6 Loading Functions and Function Dependencies</A></H2>
  318.  
  319.  
  320. <P>Functions definitions are treated just like any other valid
  321. statements. Since function definitions are mostly stored in files
  322. for re-use, you will need to know how to load the program statements
  323. within a file into Rlab's workspace. There are three main methods
  324. for performing this task:</P>
  325. <P>
  326. <UL>
  327. <LI> The <CODE>load</CODE> function reads the argument (a string), and
  328. reads that file, interpreting the file's contents as Rlab
  329. program(s). The file is read, and interpreted, regardless of
  330. file modification or access times.
  331. </LI>
  332. <LI> the <CODE>rfile</CODE> statement is a short-cut to the <CODE>load</CODE>
  333. statement. Additionally, <CODE>rfile</CODE> searches a pre-defined
  334. path of directories to files (ending in <CODE>.r</CODE>) to
  335. load. The file is read, and interpreted, regardless of file
  336. modification or access times.
  337. </LI>
  338. <LI> The <CODE>require</CODE> statement, is similar to the <CODE>rfile</CODE>
  339. statement, except it only loads the specified file
  340. once. <CODE>require</CODE> looks for a user-function with the same
  341. name as the argument to <CODE>require</CODE>, loading the file if,
  342. and only if, a user-function of the same name cannot be
  343. found. File access and/or modification times are not
  344. considered. </LI>
  345. </UL>
  346. </P>
  347.  
  348. <H3>How a function is Loaded</H3>
  349.  
  350.  
  351. <P>Some discussion of the "behind the scenes work" that occurs when a
  352. function is loaded is warranted. Although not absolutely necessary,
  353. understanding this process will help the reader write more
  354. complicated programs efficiently.</P>
  355. <P>
  356. <UL>
  357. <LI> The file is opened, and its contents are read.
  358. </LI>
  359. <LI> As the program statements are read, they are compiled and
  360. executed. Thus, as Rlab encounters global program statements,
  361. they are executed. Function definitions (assignments) are
  362. global program statements. So... function definitions get
  363. compiled, and stored as they are read.
  364. </LI>
  365. <LI> Variable (this includes) functions references are resolved
  366. at compile-time. A variable can be UNDEFINED as long as it is
  367. resolved before statement execution. Thus a function can
  368. reference other functions, that have not been previously
  369. defined; as long as these references are resolved before the
  370. function is executed.
  371. </LI>
  372. <LI> When the file's end mark (EOF) is encountered, the file is
  373. closed, and execution returns to its previous environment. </LI>
  374. </UL>
  375. </P>
  376. <P>Some examples will make the previous remarks more meaningful.</P>
  377.  
  378. <H3>Example-1</H3>
  379.  
  380.  
  381. <P>The following file contains a trivial function
  382. definition/assignment. Note that the variable (function) <CODE>y</CODE> is
  383. undefined.</P>
  384. <P>
  385. <HR>
  386. <PRE>
  387. x = function ( A )
  388. {
  389.   return y(A);
  390. };
  391. </PRE>
  392. <HR>
  393. </P>
  394. <P>Now, we will load the file (<CODE>ex-1.r</CODE>). Note that there are no
  395. apparent problems until the function is actually executed.</P>
  396. <P>
  397. <BLOCKQUOTE><CODE>
  398. <PRE>
  399. > load("./ex-1.r");
  400. > x(3)
  401. cannot use an undefined variable as a function
  402. ERROR: ../rlab: function undefined
  403.         near line 3, file: ./ex-1.r
  404. </PRE>
  405. </CODE></BLOCKQUOTE>
  406. </P>
  407. <P>Now, we can define <CODE>y</CODE> to be a function, and <CODE>x</CODE> will
  408. execute as expected.</P>
  409. <P>
  410. <BLOCKQUOTE><CODE>
  411. <PRE>
  412. > y = function ( A ) { return 3*A; };
  413. > x(3)
  414.         9  
  415. </PRE>
  416. </CODE></BLOCKQUOTE>
  417. </P>
  418.  
  419. <H3>Example-2</H3>
  420.  
  421.  
  422. <P>Understanding how files are loaded will help the efficiency of your
  423. functions. For example, functions are often written which depend
  424. upon other functions. Resolving the dependencies within the file
  425. that contains the function is common, for example, lets use the
  426. previous file (<CODE>ex-1.r</CODE>). We know that the function <CODE>x</CODE>
  427. depends upon the function <CODE>y</CODE>, so we will put a <CODE>rfile</CODE>
  428. statement within the file <CODE>ex-1.r</CODE>, which we will now call
  429. <CODE>ex-2.r</CODE>. </P>
  430. <P>
  431. <HR>
  432. <PRE>
  433. rfile y
  434.  
  435. x = function ( A )
  436. {
  437.   return y(A);
  438. };
  439. </PRE>
  440. <HR>
  441. </P>
  442. <P>Note that the <CODE>rfile</CODE> statement is exterior to the function; it
  443. is a global program statement. Thus, the file <CODE>y.r</CODE> will get
  444. loaded once, and only once when the file <CODE>ex-2.r</CODE> is loaded.</P>
  445. <P>
  446. <BLOCKQUOTE><CODE>
  447. <PRE>
  448. > rfile ex-2
  449. > x(4)
  450.        12  
  451. </PRE>
  452. </CODE></BLOCKQUOTE>
  453. </P>
  454. <P>We could have put the <CODE>rfile</CODE> or <CODE>load</CODE> statement within
  455. the function definition. But, then the file <CODE>y.r</CODE> would get
  456. loaded every time the function <CODE>x</CODE> was executed! Performance
  457. would be worse than if the <CODE>rfile</CODE> statement was a global
  458. statement, especially if the function was used within a for-loop!</P>
  459.  
  460.  
  461.  
  462. <H3>Restrictions</H3>
  463.  
  464.  
  465. <P>Although there has been no reason for the user to infer that there
  466. are limitations on the number of functions per file, or the way
  467. function comments must be formatted, the fact that there are no
  468. restrictions in these matters must be explicitly stated because
  469. other interpreted languages often make such restrictions.</P>
  470. <P>
  471. <UL>
  472. <LI> There are no restrictions on the number of function definitions
  473. within a single file.
  474. </LI>
  475. <LI> There are no restrictions on how a functions comments must be
  476. formatted to work with the online help system. When the help
  477. command is used, the <EM>entire</EM> contents of the named file
  478. are displayed on the screen (usually via a pager). The user
  479. can view comments at the top of the file, or look at the
  480. entire function.
  481. </LI>
  482. <LI> There are no restrictions on the type of programs stored in
  483. files. Simple user-functions can be stored, as well as global
  484. program statements, or any mixture of the two.
  485. </LI>
  486. </UL>
  487. </P>
  488.  
  489.  
  490.  
  491.  
  492. <H2><A NAME="ss6.7">6.7 Static Variables</A></H2>
  493.  
  494.  
  495. <P>Static variables, or file-static variables are variables that are
  496. only visible within the file in which they are declared. The syntax
  497. for the static-declaration is:</P>
  498. <P>
  499. <BLOCKQUOTE>
  500. static ( <EM>var1</EM>, <EM>var2</EM>, ... <EM>varN</EM> )
  501. </BLOCKQUOTE>
  502. </P>
  503. <P>File-static variables are accessible by all program statements after
  504. the static declaration. All functions have access to file-static
  505. variables as if they were local variables, no special declarations
  506. are necessary.</P>
  507. <P>Since functions are variables, functions can be hidden within a file
  508. with the static declaration. These functions are only accessible to
  509. program statements within that particular file. This technique is
  510. very useful for writing function toolboxes or libraries, since it
  511. eliminates the problem of global variables accidentally colliding
  512. with toolbox variables.</P>
  513.  
  514.  
  515.  
  516. <H2><A NAME="ss6.8">6.8 Help for User Functions</A></H2>
  517.  
  518.  
  519. <P>Although help for user-functions has already been eluded to, it is
  520. worth covering in detail. By convention, all the documentation
  521. necessary to use a function, or a library of functions is included
  522. within the same file, in the form of comments. This practice is very
  523. convenient since your function is never without
  524. documentation. Rlab's online help system is very simple. when a user
  525. types <CODE>help eig</CODE> (for example) Rlab looks for a help file named
  526. <CODE>eig</CODE> in the designated help directory. If the file <CODE>eig</CODE>
  527. cannot be found, the rfile search path is checked for files named
  528. <CODE>eig.r</CODE>. If a file named <CODE>eig.r</CODE> is found, its entire
  529. contents are displayed in the terminal window. Normally some sort of
  530. paging program is used, such as <CODE>more(1)</CODE>, which allows the
  531. user to terminate viewing the file at any time.</P>
  532.  
  533.  
  534.  
  535.  
  536. <HR>
  537. <A HREF="rlab-ref-5.html"><IMG SRC="prev.gif" ALT="Previous"></A>
  538. <A HREF="rlab-ref-7.html"><IMG SRC="next.gif" ALT="Next"></A>
  539. <A HREF="rlab-ref.html#toc6"><IMG SRC="toc.gif" ALT="Contents"></A>
  540. </BODY>
  541. </HTML>
  542.