BTW here is an example of an assign() function that Brad mentioned. It works
smoothly under the current implementation:
class SymmMatrix {
var data: real;
proc printme() { writeln("SymmMatrix ", this); }
}
class FockMatrix: SymmMatrix {
proc printme() { writeln("FockMatrix ", this); }
}
proc assign(left: SymmMatrix, right: real) {
left.data = right;
left.printme(); // for entertainment purposes
}
var c: SymmMatrix;
var d: FockMatrix;
c = new SymmMatrix();
assign(c,111.0); // actual and formal types match
delete c;
c = new FockMatrix();
assign(c,222.0); // dynamic type is a subclass
delete c;
d = new FockMatrix();
assign(d,333.0); // static type is a subclass
delete d;
Vass
On 02/13/17 17:43, Brad Chamberlain wrote:>
>
> Hi Orian --
>
> I haven't had a lot of time to dig into your example today, but wanted to
> make sure we got you a response before the end of the day. Others on the
> team who are more expert with this part of the compiler/language may tag onto
> what I say here. I also want to thank my colleague Vass for a lot of help in
> creating this response.
>
> I think your code is running afoul of a few things which the Chapel compiler
> should be helping to guard you against but, unfortunately, isn't at present.
>
> First, as background, I want to make sure it's clear that if you're coming
> from a C/C++ world, you should think of a Chapel record as being like a
> struct/class and a Chapel class as being like a pointer to a struct/class.
>
> The first issue that made me nervous in your code is that it hasn't been our
> intention to support assignment overloads between Chapel class variables.
> However, there is also currently nothing in the compiler that prevents it.
> Personally, I get nervous that if assignment between classes means anything
> other than "copy the rhs object pointer/ref into the lhs one" that it could
> cause problems with core capabilities like compiler-inserted temps/copies and
> type inference. By analogy, I believe it's the case that while C++ permits
> assignment overloads between structs, it doesn't support assignment overloads
> for pointers-to-structs (by analogy, Chapel _does_ permit assignment
> overloads for records).
>
> So one way you could proceed would be to create an 'assign()' function that
> took the LHS not by-ref. This would be similar to the '=' overload you
> created that generated the warning.
>
> [As a sidebar, one of the ways we often work around this in our own code is
> to create a record type that wraps a variable of the class type in order to
> support assignment overloads, automatic memory management, and the like on
> the record type without giving up the reference/identity semantics that the
> class variable provides. We're working on some features for the next release
> that will permit users to tap into such record-wrapped-class patterns without
> having to write all the wrapper code themselves].
>
>
> The second issue may relate to how you declare your FockMatrix variable
> (which is code that I don't think you included in your mail (?), so I'm
> guessing at this point). Specifically, if FockMatrix was declared this way:
>
> var myMat = new FockMatrix();
>
> then the Chapel compiler will infer the _static_ type of myMat to be
> FockMatrix rather than SymmMatrix. And even though FockMatrix is a subclass
> of SymmMatrix, this in itself is insufficient to support passing a variable
> of static type FockMatrix to a formal of type ref-to-SymmMatrix (as in C++).
> In order for that to be legal, you would also need to make sure that 'myMat'
> has static type of SymmMatrix, as follows:
>
> var myMat: SymmMatrix = new FockMatrix();
>
> Here's a simple example that Vass put together that works:
>
> class C { proc foo() { writeln("C::foo"); } }
> class D: C { proc foo() { writeln("D::foo"); } }
>
> proc bar (ref x: C) { x.foo(); x = new C(); x.foo(); }
>
> proc main {
> var myC: C = new D();
> myC.foo();
> bar(myC);
> myC.foo();
> }
>
> whereas if the declaration of myC is changed to:
>
> var myC = new D();
>
> then the C compilation step fails with messages similar to the ones you
> report. Vass also provides an example showing why this should be
> problematic, if it's not obvious:
>
> class C { }
> class D: C { proc print { writeln(); } }
>
> proc test(ref lhs: C) { lhs = new C(); }
>
> var d = new D();
> test(d);
> d.print; // doesn't make sense when 'd' is actually a 'C'!
>
> This is the second way that the Chapel compiler is failing you. It should
> complain loudly about passing a variable of static type 'D' to a 'ref' formal
> of type 'C' rather than letting it pass silently and having the C compilation
> step blow up. Vass opened an issue and test to track this problem today:
>
> https://github.com/chapel-lang/chapel/issues/5353
> https://github.com/chapel-lang/chapel/pull/5352
>
> (and we should open one for assignment overloads on class types as well).
>
> So, I'll be curious whether this is how you declared your SymmMatrix
> variable, and if so, whether giving it a static type fixes the issue (but
> then I'll still remain nervous about overloading assignment on it...).
>
>
> Turning to some of the specific questions in your mail:
>
>> The origin of the problem seems to be that the compiler expect a SymmMatrix
>> not a FockMatrix (even if SymmMatrix is the superclass). But then I don’t
>> understand why I have a double pointer structure (struct
>> chpl_SymmMatrix_chpl_s **) vs a single pointer structure (struct
>> chpl_FockMatrix_chpl_s *).
>
> It may be clearer by this point that one of these '*'s comes from the 'class'
> type ("pointer to struct" in C) and the other comes from the 'ref' argument
> intent.
>
>
>> I am assuming that the overloaded operators of the superclass are valid for
>> the child classes.
>> Am I right?
>
> Only if the child class variables have the superclass static type.
>
>
> Hope this is helpful,
> -Brad
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
Chapel-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/chapel-users