Ah, thank you Brad and David for your time.  This clarifies a number of things.

        Jonathan


> On Jun 26, 2017, at 10:14PM, Brad Chamberlain <[email protected]> wrote:
> 
> Hi Jonathan --
> 
> Following up on my previous response, David Iten dug into this a bit further 
> and raised a question as to whether this was truly a bug or not which we'll 
> probably need to wrestle with a bit further, but the supporting information 
> was interesting and useful.  Let's look at a simpler example:
> 
> record array_of_reals {
>   var v: [1..0] real;
> }
> 
> var A, B: array_of_reals;
> 
> A.v.push_back(1.2);
> A.v.push_back(2.3);
> writeln(A);
> 
> B = A;
> 
> writeln(B);
> 
> Here, intuitively, we'd like B to take on A's value.  But literally what's 
> happening is that B.v is a 0-element array and A.v is a 2-element array, so 
> we get an error message similar to the one you reported.  This is because the 
> default assignment for records of this type will effectively do:
> 
> B.v = A.v
> 
> and we don't support auto-resizing of arrays based on assignment, hence the 
> size/shape mismatch error.  Your program was effectively doing the same thing 
> except that it was the hash table reallocation code that was attempting to 
> copy one record into the other rather than user code.
> 
> A quick fix for this that David suggested (and which is a bit more satisfying 
> than my requestCapacity() workaround) is to change your record to store an 
> explicit domain as follows:
> 
> record array_of_reals {
>   var D: domain(1);
>   var v: [D] real;
> }
> 
> var A, B: array_of_reals;
> 
> A.v.push_back(1.2);
> A.v.push_back(2.3);
> writeln(A);
> 
> B = A;
> 
> writeln(B);
> 
> Now, the default assignment for records will be equivalent to:
> 
> B.D = A.D;
> B.v = A.v;
> 
> That is, first update v's index set (B.D) which results in resizing v, and 
> then copy the values from one v to another.
> 
> This also suggests an alternate workaround to the original program which 
> would be to add an explicit assignment overload for the array_of_reals record:
> 
> proc =(ref X: array_of_reals, Y: array_of_reals) {
>   for e in Y.v do
>     X.v.push_back(e);
> }
> 
> Doing either of these changes for your record similarly allows your test to 
> pass.
> 
> 
> For me, the slightly open semantic question is whether our associative array 
> implementation should and could be doing more to either protect the user from 
> such things (where my current guess is "no", but I'm still wrestling with it) 
> and/or whether it could generate a clearer error message in cases like this.
> 
> In any case, I hope this explanation brings slightly more closure and 
> understanding than this morning's.
> 
> -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

Reply via email to