[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Nested functions, documented?
From: |
David Shih |
Subject: |
Re: Nested functions, documented? |
Date: |
Mon, 21 Nov 2011 17:34:34 -0500 |
User-agent: |
Opera Mail/11.51 (Linux) |
| function y = primary_function(x, a, b)
| y = sub_function( @(x) sub_function(x, a, b) );
| end
Sorry. That's a mistake.
It should just instead be:
| function y = primary_function(x, a, b)
| % use anonymous function to create a closure
| func = @(x) sub_function(x, a, b);
|
| % now, when func is called at some future point, only x need to be
passed explicit; a and b are passed by the anonymous function
| z = func(x);
|
| % this is particularly useful when using functions such as arrayfun
to avoid for-loops:
| % Z = arrayfun(func, X);
| % suppose X is an array, and Z is the output array, and
sub_function(..) normally only handle x as a scalar value
| end
|
| function z = sub_function(x, a, b)
| % sub_function accesses parameter variables a and b, which are in
scope
| z = x + a + b;
| end
I forgot about the ability to write to variables in nested functions. I
typically avoid doing this, as it creates a mess.
I only really use nested functions for use with arrayfun or cellfun to
avoid for-loops and to organize a procedure inside a function for re-use.
My particular need for nested function, originally written for Matlab and
now translated to use subfunction + closure
function y = evaluate(X, kmax)
%EVALUATE(X, K)
%Return score array y based on data matrix X, where y_i corresponds to the
score of X evaluated based on parameters 1:kmax
%% for-loop version
y = zeros([kmax 1]);
for i in 1:kmax
Y(i) = evaluate_k(X, i);
end
%% arrayfun version: No for-loop!
% wrap subfunction s.t. X does not need to be explicitly passed in
function call
func = @(k) evaluate_k(X, k);
y = arrayfun(func, k);
end
function y = evaluate_k(X, k)
% complex evaluation code
% y = some final score
end
For the ability to write to shared variables, I would use classes, and
declare the shared variables as class members.
David
On Mon, 21 Nov 2011 16:25:28 -0500, John W. Eaton <address@hidden> wrote:
On 19-Nov-2011, David Shih wrote:
| I ran into the same problem where my Matlab code using nested function
is
| affected by the variable scope issue.
|
| I have not seen a workaround on the list, so I am providing one here:
|
| You can use anonymous functions with subfunctions to achieve the same
effect
| as nested functions.
| It may even be desired that the programmer explicitly pass the
variables
| into a subfunction using an anonymous function, so that nested function
| variable scopes do not become a mess.
|
|
| An example:
|
| *Nested version*:
|
| function y = primary_function(x, a, b)
|
| function z = nested_function(x)
| % nested_function accesses variables a and b from the parent
function
| z = x + a + b;
| end
|
| y = nested_function(x);
|
| end
| function y = primary_function(x, a, b)
| y = sub_function( @(x) sub_function(x, a, b) );
| end
|
| function z = sub_function(x, a, b)
| % sub_function accesses parameter variables a and b, which are in
scope
| z = x + a + b;
| end
Given that you are writing this complex expression:
y = sub_function( @(x) sub_function(x, a, b) );
which already involves A and B as arguments to the subfunction, why
not simplify things and write
y = subfunction (x, a, b);
instead?
Also, the version with the function handle trick is not equivalent to
nested functions because nested functions can change values in the
calling scope. For example, with Matlab, I think the following
program will print x = 3 and a = 4 and y will be undefined outside the
scope foo the nested function:
function foo ()
x = 1;
a = 2;
function bar (y)
y = -1;
x = 3;
a = 4;
end
bar (x);
x
a
y
end
I don't think you can get those semantics from some trick with
function handles and subfunctions because the function handle gets a
copy of the variables from the calling scope, and the subfunction
can't directly modify values in the caller.
And, I would add, those semantics are precisely what makes nested
functions such an awful software maintenance nightmare. At the very
least, a way to declare variables as local to a nested function should
have been added to the language at the same time.
jwe