Open alvaradoo opened 1 month ago
Here is a template implementation:
operator *=(ref a: ta, b: tb) where isTupleType(ta) && isTupleType(tb) && a.size == b.size {
for param i in 0..<a.size do
a(i) *= b(i);
}
Here is a template implementation:
operator *=(ref a: ta, b: tb) where isTupleType(ta) && isTupleType(tb) && a.size == b.size { for param i in 0..<a.size do a(i) *= b(i); }
Would it be better to have this loop run in parallel via a forall
loop? Maybe forall
where a.size > 10
and foreach
otherwise? But tuples are usually small and don't hold big data...
I'd expect you'd need quite a few more tuple elements for forall
to offer any benefit. Anyway for param
will allow for tuples of non-homogenous type. For example (int, uint)
. I think that might be unintentional here -- I would expect that if we want to allow *=
on tuples, it should be for only tuples with the same element type throughout (which we call "star tuples" or "homogenous tuples").
Even so, I'd probably focus on using foreach
or for param
to enable vectorization of these operations. I'd probably avoid using forall
since it's unlikely that the operation will take longer than it would to create a task.
I am not sure if agree with *=
being only allowed on homogeneous tuples. As a user, I would assume that if I can do something like below, and am allowed to use *=
with promotion on tuples, I should be able to rewrite it as (a,b) *= c
, even though it is a heterogeneous tuple. This is because to me, I often use tuples as a nice, compact way to store many variables when I need to return multiple variables, assign values between multiple variables, etc. Maybe we should defer to accepting *=
(and friends) if the types of the variables within tuples we are applying *=
to allow it.
var a:real = 2.0;
var b:int = 3;
const c:int = 2;
a *= c;
b *= c;
// might want to be able to do (a,b) *=c
@alvaradoo - the reason I was saying it shouldn't be allowed for non-homogenous tuples is that we don't allow tuple-scalar operations in such cases today.
var intIntTup = (1, 2);
var x = intIntTup * 5; // ok
writeln(x);
var intRealTup = (1, 2.0);
var y = intRealTup * 5; // fails to resolve
writeln(y);
We might have limited tuples in this way to prevent code from getting too confusing. I haven't tracked down the justification.
We might have limited tuples in this way to prevent code from getting too confusing. I haven't tracked down the justification.
I think that's the case. IIRC, we originally supported promotion across homog. and het. tuples; then got nervous about the het. case and removed all promotion; then realized how much we missed the homog. case and re-instated it. I think we discussed potentially supporting the het. case through a utility module (i.e., not by default), but I don't think anybody ever missed it enough to take that work on.
Summary of Feature
Description: Currently, one can rewrite an assignment of multiple variables as tuple packing. This feature request is to add the ability to not only do this with assignment, but also with the
*=
operator and others. These would include+=
,-=
, and/=
. I provide more details and ideas in the code sample below.Is this issue currently blocking your progress? Nope!
Code Sample
The main goal is to have operations like these below possible.
However, should we also consider allowing for operations when the LHS is a tuple and the RHS is just some variable? If the operations of
A = cArr
andB = cArr
are legal, then maybe we should consider allowing the operations below for nicer code. Further, we do allow of promotion for array operations such asaArr *= 2
, so this feels like it falls into the same vein, and should be alright to be supported.