For a tuple such as x : 2*real, it seems to support various element-wise operations, for example
var t = (1.0, 2.0); // type = (real,real) or 2*real
writeln( t ); // (1.0, 2.0)
writeln( t + 0.1 ); // (1.1, 2.1)
writeln( t * 10.0 ); // (10.0, 20.0)
writeln( t * 10.0 + 1.0 ); // (11.0, 21.0)
writeln( t ** 2 ); // (1.0, 4.0)
but an assignment of scalar to a tuple such as
t = 0.0; // my expected result: t = (0.0, 0.0)
gives an error:
error: Cannot assign to 2*real(64) from real(64)
Is this prohibited because the conversion of a scalar to a tuple is not well-defined or ambiguous, or possibly for other reasons? If so, is the user expected to write a custom assignment routine ike proc =(t, x) (to overload =)?
Hi @voidwkr: I believe that we chose to make this illegal in Chapel conservatively, worried that if someone failed to recognize that the left-hand side expression was a tuple, it might catch them by surprise. There's also potentially a little bit of a question around what should be done in the case of a heterogeneous tuple on the left-hand side.
That said, I also think that there's an argument to be made to support such assignments given the other tuple-scalar combinations that Chapel supports, as you observe (not to mention array<-scalar assignments).
When in doubt on questions like this, we often try to take the conservative approach because then if we decide later that we're wrong, we're less likely to break existing code. If you believe we've made the wrong choice here, I'd encourage you to open a feature request on Chapel's GitHub issues page making your case: https://github.com/chapel-lang/chapel/issues
As you note, one way to support such assignments would be to provide your own overload of = to handle that case like so (TIO):
var t = (1.0, 2.0); // type = (real,real) or 2*real
t = 0.0;
writeln(t);
proc =(ref lhs: 2*real, rhs: real) {
for l in lhs do
l = rhs;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With