Nested functions are similar to subfunctions in that only the main function is visible outside the file. However, they also allow for child functions to access the local variables in their parent function. This shared access mimics using a global variable to share information — but a global variable which is not visible to the rest of Octave. As a programming strategy, sharing data this way can create code which is difficult to maintain. It is recommended to use subfunctions in place of nested functions when possible.
As a simple example, consider a parent function
foo, that calls a nested
bar, with a shared variable x.
function y = foo () x = 10; bar (); y = x; function bar () x = 20; endfunction endfunction foo () ⇒ 20
Notice that there is no special syntax for sharing x. This can lead to problems with accidental variable sharing between a parent function and its child. While normally variables are inherited, child function parameters and return values are local to the child function.
Now consider the function
foobar that uses variables x and
foobar calls a nested function
foo which takes
x as a parameter and returns y.
foo then calls
which does some computation.
function z = foobar () x = 0; y = 0; z = foo (5); z += x + y; function y = foo (x) y = x + bat (); function z = bat () z = x; endfunction endfunction endfunction foobar () ⇒ 10
It is important to note that the x and y in
zero, as in
foo they are a return value and parameter respectively. The
bat refers to the x in
Variable inheritance leads to a problem for
eval and scripts. If a
new variable is created in a parent function, it is not clear what should
happen in nested child functions. For example, consider a parent function
foo with a nested child function
function y = foo (to_eval) bar (); eval (to_eval); function bar () eval ("x = 100;"); eval ("y = x;"); endfunction endfunction foo ("x = 5;") ⇒ error: can not add variable "x" to a static workspace foo ("y = 10;") ⇒ 10 foo ("") ⇒ 100
The parent function
foo is unable to create a new variable
x, but the child function
bar was successful. Furthermore, even
eval statement y in
bar is the same y as in its
foo. The use of
eval in conjunction with nested
functions is best avoided.
As with subfunctions, only the first nested function in a file may be called from the outside. Inside a function the rules are more complicated. In general a nested function may call:
As a complex example consider a parent function
ex_top with two
ex_b. In addition,
ex_a has two
more child functions,
ex_ab. For example:
function ex_top () ## Can call: ex_top, ex_a, and ex_b ## Can NOT call: ex_aa and ex_ab function ex_a () ## Can call everything function ex_aa () ## Can call everything endfunction function ex_ab () ## Can call everything endfunction endfunction function ex_b () ## Can call: ex_top, ex_a, and ex_b ## Can NOT call: ex_aa and ex_ab endfunction endfunction