bugGNU Octave - Bugs: bug #48802, function overload resolution on...

 
 

bug #48802: function overload resolution on function handles fails on classdef methods defined in class body

Submitter:  Mike Miller <mtmiller>
Submitted:  Tue 16 Aug 2016 07:49:35 PM UTC
   
 
Category:  Interpreter Severity:  1 - Wish
Priority:  5 - Normal Item Group:  Matlab Compatibility
Status:  Fixed Assigned to:  None
Originator Name:  Open/Closed:  * Closed
Release:  * dev Operating System:  * Any
Fixed Release:  None Planned Release:  None
* Mandatory Fields

Add a New Comment Rich Markup
   

Jump to the original submission

Sun 10 Mar 2019 06:39:49 PM UTC, comment #9: 

No response, asumming the patch mentioned in comment #8 has resolved the problem.  Closing report.

Rik <rik5>
Group administrator
Tue 05 Mar 2019 11:15:04 PM UTC, comment #8: 

I believe this problem is fixed with the following changeset:

http://hg.savannah.gnu.org/hgweb/octave/rev/8bd9fd99c12a

John W. Eaton <jwe>
Group administrator
Tue 05 Mar 2019 05:11:54 PM UTC, comment #7: 


>> c1_obj = c1 ();
>> c2_obj = c2 ();
>> m1_fh = c2_obj.m1_h ();
>> sin_fh = c2_obj.sin_h ();
>> m1_fh (pi)  %% m1 or error from c2:m1 about wrong type?
m1
    3.1416

>> m1_fh (c2_obj)  %% c2:m1, I assume
c2:m1
>> m1_fh (c1_obj)  %% c1:m1, or error from c2:m1 about wrong type?
m1
  c1 with no properties.

>> sin_fh (pi)  %% built-in sin or error from c2:sin about wrong type?

ans =

   1.2246e-16

>> sin_fh (c2_obj)  %% c2:sin, I assume
c2:sin
>> fh = @sin;
>> fh (pi)      %% built-in sin, I assume.

ans =

   1.2246e-16

>> fh (c2_obj)  %% c2:sin or error from built-in sin about wrong type?
c2:sin


Guillaume <gyom>
Sun 03 Mar 2019 11:44:27 PM UTC, comment #6: 

Oops, I think my tests had some errors.  Instead of making hte methods static, they should have been called for the objects c1_obj and c2_obj instead of the class names c1 and c2.  And there was also a syntax error in one of the classes.

New versions of the files attached.  It would be helpful if someone could run this example and report the results.  You'll need to save c1.m, c2.m, and m1.m in separate files and then execute each line of the "code" section individually since some of those may cause errors.





(file #46407)

John W. Eaton <jwe>
Group administrator
Wed 20 Feb 2019 10:36:30 AM UTC, comment #5: 

Regarding comment #3:  In the original example I get:


% ML18 (error): The class c2 has no Constant property or Static method named 'm1_h'.
% OCT6 (error): method `m1_h' is not static
m1_fh = c2.m1_h ();

% ML18 (error): The class c2 has no Constant property or Static method named 'sin_h'.
% OCT6 (error): method `sin_h' is not static
sin_fh = c2.sin_h ();


Changing all methods to be static in c2 the output of run_test.m:


>> c1_obj = c1 ();
>> c2_obj = c2 ();
>> m1_fh = c2.m1_h ();
>> sin_fh = c2.sin_h ();

>> m1_fh (pi)  %% m1 or error from c2:m1 about wrong type?
m1
    3.1416

>> m1_fh (c2_obj)  %% c2:m1, I assume
m1
  c2 with no properties.

>> m1_fh (c1_obj)  %% c1:m1, or error from c2:m1 about wrong type?
c1:m1

>> sin_fh (pi)  %% built-in sin or error from c2:sin about wrong type?

ans =

   1.2246e-16

>> sin_fh (c2_obj)  %% c2:sin, I assume
Undefined function 'sin' for input arguments of type 'c2'.

>> fh = @sin;
>> fh (pi)      %% built-in sin, I assume.

ans =

   1.2246e-16

>> fh (c2_obj)  %% c2:sin or error from built-in sin about wrong type?
Undefined function 'sin' for input arguments of type 'c2'.


Test follows in the next post.

Kai Torben Ohlhus <siko1056>
Group Member
Fri 15 Feb 2019 06:11:40 PM UTC, comment #4: 

I can't test that for you, but Matlab fundamental classes are documented at https://www.mathworks.com/help/matlab/matlab_prog/fundamental-matlab-classes.html, all builtin numeric types, logical, char, struct, cell, and table.

I don't know what they are trying to say with "a function in a class that is not a fundamental Matlab class", since they don't give a counterexample. When would the binding ever occur at the time of declaration? I have no idea. That seems like another inconsistency, I would expect function handles to always be symbolic and only bind to the function when they are invoked with their arguments.

Mike Miller <mtmiller>
Group Member
Thu 07 Feb 2019 07:52:06 PM UTC, comment #3: 

I'm a bit confused by the statement in the Matlab docs that is quoted in the original submission.  What is meant by "if the function you specify overloads a function in a class that is not a fundamental Matlab class"?  What is a "fundamental Matlab class"?  Is that a type like in32 or double or struct, or any class that is distributed as a part of Matlab, or what?

I think I may need some more examples to understand how things are expected to work.

What is supposed to happen for the following


% c1.m:

classdef c1
  methods
    function m1 (obj)
      disp ('c1:m1');
    end
  end
end

% c2.m:

classdef c2
  methods
    function m1 (obj)
      disp ('c2:m1');
    end
    function sin (obj)
      disp ('c2:sin');
    function fh = m1_h (obj)
      fh = @m1;  %% Does this always bind to c2:m1
                 %% or can lookup rules result in a
                 %% call to another function if arg
                 %% is not c2 object?
    end
    function fh = sin_h (obj)
      fh = @sin;
    end
  end
end

% m1.h:

function m1 (x)
  disp ('m1');
  disp (x);
end

% code:

c1_obj = c1 ();
c2_obj = c2 ();
m1_fh = c2.m1_h ();
sin_fh = c2.sin_h ();

m1_fh (pi)  %% m1 or error from c2:m1 about wrong type?
m1_fh (c2_obj)  %% c2:m1, I assume
m1_fh (c1_obj)  %% c1:m1, or error from c2:m1 about wrong type?

sin_fh (pi)  %% built-in sin or error from c2:sin about wrong type?
sin_fh (c2_obj)  %% c2:sin, I assume

fh = @sin;
fh (pi)      %% built-in sin, I assume.
fh (c2_obj)  %% c2:sin or error from built-in sin about wrong type?


I guess my question is, precisely when is binding deferred?

John W. Eaton <jwe>
Group administrator
Fri 04 Jan 2019 08:11:05 PM UTC, comment #2: 

The problem seems to be that the function make_fcn_handle in ov-fcn-handle.cc does the wrong thing.  It is called when evaluating the "@double" expression in an attempt to bind the function handle early.  It works for overloaded methods if they are defined in a separate file because it does search the loadpath for overloaded function names.  But to do that for methods in classdef classes would require parsing all possible classdef files just to find out whether there are some overloads.  So the right thing seems to be to avoid binding function handles until they are called since there is no reasonable way to determine what function to call until a call is actually attempted with arguments.  But the fix is not as simple as just having a function handle store the name of the function.  It needs more context than that to properly resolve subfunctions, nested functions, local functions, etc.  So I see no simple fix.  This bug should probably also reference the one about handles to nested functions, bug #39257.  These issues are related and I think fixing them properly will require a bit of work.

John W. Eaton <jwe>
Group administrator
Sat 20 Aug 2016 08:42:46 PM UTC, comment #1: 

This bug only applies to classdef function overloads that are defined in the "methods" block of a class definition.

For old-style classes, all methods are defined in separate .m function files. If this is also done for a classdef class, then this bug does not apply.

Mike Miller <mtmiller>
Group Member
Tue 16 Aug 2016 07:49:35 PM UTC, original submission:  

According to the Matlab documentation, a function handle should behave with respect to overloading the same way as any other function call would.

> Overloading — If the function you specify overloads a function in a class that is not a fundamental MATLAB class, the function is not associated with the function handle at the time it is constructed. Instead, MATLAB considers the input arguments and determines which implementation to call at the time of evaluation.


(From https://www.mathworks.com/help/matlab/matlab_prog/creating-a-function-handle.html.)

In other words, if I have a user-defined class that implements a double() conversion method,


a = 42;
b = someclass ();
fn = @double;
x = fn (a);
y = fn (b);


this snippet should work correctly. Currently, Octave throws a "invalid conversion from object to double" error.

Mike Miller <mtmiller>
Group Member

 

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

Attach Files:
   
   
Comment:
   

Attached Files
file #46407:  test-code.txt added by jwe (1KiB - text/plain)
file #46312:  bug48802_comment03.zip added by siko1056 (857B - application/zip)

 

Carbon-Copy List
  • -email is unavailable- added by rik5 (Posted a comment)
  • -email is unavailable- added by gyom (Posted a comment)
  • -email is unavailable- added by siko1056 (Posted a comment)
  • -email is unavailable- added by jwe (Posted a comment)
  •  

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

    Only group members can vote.

     

    Follow 10 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2019-03-10 rik5 StatusReady For Test Fixed
        Open/ClosedOpen Closed
    2019-03-05 jwe StatusConfirmed Ready For Test
    2019-03-03 jwe Attached File- Added test-code.txt, #46407
    2019-02-20 siko1056 Attached File- Added bug48802_comment03.zip, #46312
    2019-02-15 mtmiller Carbon-CopyRemoved 80942 -
    2019-01-04 mtmiller Dependencies- bugs #55383 is dependent
    2016-08-20 mtmiller StatusNone Confirmed
        Summaryfunction overload resolution should be performed on function handles function overload resolution on function handles fails on classdef methods defined in class body
    2016-08-20 mtmiller Dependencies- bugs #48837 is dependent

    Back to the top

    Powered by Savane 3.13-3230.
    Corresponding source code