octave-bug-tracker
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Octave-bug-tracker] [bug #56856] Matlab calls class subsasgn method wit


From: anonymous
Subject: [Octave-bug-tracker] [bug #56856] Matlab calls class subsasgn method with array of double instead of class type
Date: Mon, 9 Sep 2019 18:07:01 -0400 (EDT)
User-agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:69.0) Gecko/20100101 Firefox/69.0

Follow-up Comment #7, bug #56856 (project octave):

Thanks for looking into this issue!

I agree that this behavior appears in a very specific situation. I have
however seen quite often people use a loop to grow a variable, as in

for i = 1:10
    a(i) = f(i);
end

This is of course not the best code, but it is also very easy and natural for
small loops, so people just use it (and I don't have control over that). In
fact it is also supported in Octave (e.g. set 'f = @(x) x;'). When the
function f produces a class object, this directly leads to the current issue.

> It seems prudent to me to avoid relying on the type or dimensions of the
left hand side value, other than to do the assignment that the subsasgn call
is providing. 
I'm not sure exactly what you mean here: isn't it crucial to be able to
evaluate the type and size of the left-hand-side of an assignment in order to
perform this assignment correctly? For instance, if 'x(10)=2' is called on an
object x which has only 9 elements, then the size of this object first needs
to be increased before the value of '2' can be assigned to its 10th element,
right?

>From the point of view of a class developer, I see one very big reason why the
current octave behavior is problematic. It is seen when running the same two
commands below in octave:


octave:1> a=test;
calling the test constructor
octave:2> x(10)=a
Calling test.subsasgn(val, idx, rhs).
val is of type 'test':
val =

<object array test>

idx is of type 'struct':
idx =

  scalar structure containing the fields:

    type = ()
    subs = 
    {
      [1,1] =  10
    }

rhs is of type 'test':
rhs =

<object test>

Now we check the size of 'val':
Calling test.size.
warning: size: some elements in list of return values are undefined
warning: called from
    size at line 4 column 1
    subsasgn at line 11 column 5
[](0x0)
warning: subsasgn: some elements in list of return values are undefined
warning: called from
    subsasgn at line 12 column 1
x = [](0x0)


Ok, this produces an error, but the real issue is at the beginning: variable
'val' is provided to the function 'subsasgn' without being constructed... it
is of type 'test', but the test class constructor has not been called: an
object was created without calling the class constructor. Isn't this in
contradiction with the very basis of object oriented programming? What is this
if not a source of unspecified behaviors? Honestly, if an object oriented
language requires you to deal with un-initialized objects, then either it is
actually not an object oriented language, or there is a problem with the
language!

One way to avoid this could be to call the class constructor with an empty
input since we know nothing about 'x', e.g. an empty array. But this would
require that every class constructor should implement a default constructor,
which I don't think is currently a requirement.

Another solution would be not to interpret the type of undeclared variables
further than necessary (an empty array then seem like a reasonable common
ground for all situations). It looks to me that this is the solution chosen by
matlab, and I think it has the merit of being free of presuppositions: why
should 'x(10) = a' produce by default an 'x' which is of the same type as 'a'?
If 'a' represents the image of a function, then 'x' should represent the
function which sends 10 to a, and is therefore of a different type. But if an
empty 'x' is interpreted as being of the same class as 'a' even though the
user did not specify so, then this reduced the set of possibilities.

Also, after all, subsasgn is just another function. So if an empty argument
can be interpreted in a context-dependent way for this function, why shouldn't
it be like that for other functions as well?!? I see no reason to open this
pandora box.

    _______________________________________________________

Reply to this item at:

  <https://savannah.gnu.org/bugs/?56856>

_______________________________________________
  Message sent via Savannah
  https://savannah.gnu.org/




reply via email to

[Prev in Thread] Current Thread [Next in Thread]