bugGNU Octave - Bugs: bug #59989, Wrong scope of nested function in...


bug #59989: Wrong scope of nested function in anonymous function handle

Submitted by:  Markus Mützel <mmuetzel>
Submitted on:  Tue 02 Feb 2021 07:55:07 AM UTC  
Category:  Interpreter Severity:  3 - Normal
Priority:  5 - Normal Item Group:  Regression
Status:  Fixed Assigned to:  None
Originator Name:  Open/Closed:  Closed
Release:  6.1.0 Operating System:  Any

Add a New Comment (Rich Markup)

You are not logged in

Please log in, so followups can be emailed to you.


( Jump to the original submission)

Wed 03 Feb 2021 02:52:38 AM UTC, comment #6: 

Thanks for checking.  I agree, we should make a 6.2.0 release soon.  There are a few bugs I'd like to try to fix first.  We can discuss here:  https://octave.discourse.group/t/plans-for-octave-6-2/629

John W. Eaton <jwe>
Project Administrator
Tue 02 Feb 2021 11:13:54 PM UTC, comment #5: 

This works for me now as tested on the stable branch.  Seems like we need to get a 6.1.1 bug fix release out soon.

Closing report.

Rik <rik5>
Project Administrator
Tue 02 Feb 2021 09:41:55 PM UTC, comment #4: 

The following change seems to do the right thing for me.  I pushed it on stable and merged with default.


Marking as ready for test.

John W. Eaton <jwe>
Project Administrator
Tue 02 Feb 2021 08:48:34 PM UTC, comment #3: 

Oops, wait, I was wrong about the fix in comment #2.  But I think something like that change is needed here.

John W. Eaton <jwe>
Project Administrator
Tue 02 Feb 2021 06:15:39 PM UTC, comment #2: 

I think the attached change fixes the problem.

(file #50825)

John W. Eaton <jwe>
Project Administrator
Tue 02 Feb 2021 04:19:35 PM UTC, comment #1: 

This code is making use of a feature which is relatively obscure and which certainly doesn't get a lot of testing.  Nested functions within a larger function are supposed to have access to the namespace of the enclosing function.  Hence, it is possible to define the equivalent of a pseudo-global variable that is seen by all nested functions without having to be explicitly passed as a parameter.

This should be fixed in Octave, but as a point of coding it is usually better to pass data to a function for processing.  In software architecture this allows the code to be modular and to guarantee that a function can only modify, potentially, inputs passed to it and have no other side effects.  With global variables, it can be very difficult because any code, any where could potentially change the value.

One possible justification for not re-coding is if the variable is very large such that passing it down to each function would be a performance hit.  The notes in the code say that the variable 'a' is hard to calculate, but don't say whether it is large.  If it just takes a lot of code to calculate a single constant value then it would be better to pass 'a' down.  If 'a' is a large matrix then this does not apply.

Here is a simplified function which exhibits the same behavior.

function retval = tst_nestfcn ()
  x = pi;

  function y = nestfcn1 ()
    y = x;

  function y = nestfcn2 (h)
    y = h();

  retval = nestfcn2 (@nestfcn1);        # WORKS
  retval = nestfcn2 (@() nestfcn1());   # FAILS


Rik <rik5>
Project Administrator
Tue 02 Feb 2021 07:55:07 AM UTC, original submission:  

Like reported on the discourse forum [1], calling the following function fails in Octave 6.1.0:

function topLevelFunction()

  % Helper anonymous function - used to pack/unpack design variables in actual code.
  unpacker = @(x) sum( x );

  % Optimisation objective function - required soem other data passed through
  % using anonymous function in call to solver.
  function [ x ] = objFcn( x , a )

    x = a + unpacker( x );

  end % function nf

  % Dummy solver - actually using leasqr.
  function [ y ] = solver( funcHandle )

    % Solver determine design values.
    x = [ 2 , 3 ];

    % Call objective function to get value.
    y = funcHandle( x );

  end % function

  % Fixed data needed by objective function. Actually a heap of stuff requiring
  % complex calculation.
  a = 1;

  % Call optmiser.
  % Octave 5.2.0, as shipped on Ubuntu 20.04 - OK.
  % Octave 6.1.0, self compiled - FAIL:
  %  error: 'unpacker' undefined near line 10, column 10
  %  error: called from
  %  topLevelFunction>objFcn at line 10 column 7
  %  topLevelFunction>@<anonymous> at line 38 column 20
  %  topLevelFunction>solver at line 21 column 7
  %  topLevelFunction at line 38 column 5
  y = solver( @(x) objFcn( x , a )  )

end % function  topLevelFunction

The same function executes without error in Octave 5.2 and with Matlab R2020b.

The expected output is:

>> topLevelFunction2
y = 6

In Octave 6.1.0, the function fails with the following error:

>> topLevelFunction
error: 'unpacker' undefined near line 10, column 10
error: called from
     >objFcn at line 10 column 7
     >@<anonymous> at line 38 column 20
     >solver at line 21 column 7
     topLevelFunction at line 38 column 5

[1]: https://octave.discourse.group/t/anonymous-function-scope-change-from-5-2-0-to-6-1-0/701

Markus Mützel <mmuetzel>
Project Member


(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach Files:

Attached Files
file #50825:  anon-fcn-diffs.txt added by jwe (1KiB - text/plain)
file #50821:  topLevelFunction.m added by mmuetzel (1KiB - text/plain)


Depends on the following items: None found

Items that depend on this one: None found


Carbon-Copy List
  • -email is unavailable- added by jwe (Updated the item)
  • -email is unavailable- added by rik5 (Posted a comment)
  • -email is unavailable- added by mmuetzel (Submitted the item)

    Do you think this task is very important?
    If so, you can add your encouragement to it.
    This task has 0 encouragements so far.

    Only project members can vote.




    Follow 6 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2021-02-02 rik5 StatusReady For Test => Fixed
        Open/ClosedOpen => Closed
    2021-02-02 jwe StatusPatch Submitted => Ready For Test
    2021-02-02 jwe Attached File- => Added anon-fcn-diffs.txt, #50825
        StatusConfirmed => Patch Submitted
    2021-02-02 mmuetzel Attached File- => Added topLevelFunction.m, #50821

    Back to the top

    Powered by Savane 3.7