Let's say I'm generating tuples and I want to concatenate them as they come. How do I do this? The following does element-wise addition:
if ts = ("foo", "cat")
, t = ("bar", "dog")
ts += t
gives ts = ("foobar", "catdog")
,
but what I really want is ts = (("foo","cat"),("bar","dog"))
.
So I guess the first question is "does Chapel support tuple concatention?", then "is there a binary operator/function for it?", then "if not, what is a good way to do it?", and lastly "make my life easier if you know a better way of living".
Please address the questions in order.
I appreciate the help!!
the first question is "does Chapel support tuple concatention?"
I believe the answer here is "no" for the following reason: (1) A Chapel variable has a single static type that cannot change over its lifetime, and (2) a tuple's type is defined as its static number of elements as well as the type of each element. Thus, given your variable ts
ts = ("foo", "cat")
its type is 2*string
("a 2-tuple of strings") and this would prevent it from ever being able to store the value (("foo","cat"),("bar","dog"))
since its type is 2*(2*string)
("a 2-tuple of 2-tuples of strings"). So while these two tuples have the same number of elements (2), they differ in their element types ("string" vs. "2-tuple of string") and therefore aren't the same type (aren't compatible).
"is there a binary operator/function for it?"
Due to the above, no.
then "if not, what is a good way to do it?"
A few things come to mind, but may or may not be helpful depending on your specific situation. Rather than trying to re-assign ts
, you could create a new tuple that was a tuple-of-tuples:
const ts2 = (ts, t);
and you could even do this recursively in a routine, though that would likely end up blowing up your code size if the tuple grew to any significant length (because each call to the function would generate a tuple of a different type and unique code for it).
From what I'm seeing in your question, I think you may want to use a list of tuples or a 1D array (vector) of tuples. Here's a list-based approach:
use List;
var listOfTups: list(2*string);
listOfTups.append(("foo", "cat"));
listOfTups.append(("bar", "dog"));
writeln(listOfTups);
And here's an array-based approach:
var arrOfTups: [1..0] 2*string;
arrOfTups.push_back(("foo", "cat"));
arrOfTups.push_back(("bar", "dog"));
writeln(arrOfTups);
Of the two, I would recommend the array-based approach because arrays are much more first-class and powerful in Chapel (they enjoy syntactic support, permit data parallelism, support promotion of scalar functions and operators, etc.) whereas lists are just a convenience library.
and lastly "make my life easier if you know a better way of living".
One other related thing I can think of to mention if you're not aware of it is that "varargs" functions in Chapel effectively convert those arguments to tuples. So given:
proc myFunc(x...) {
writeln(x.type:string);
}
myFunc(("foo", "cat"), ("bar", "dog"));
the output is:
2*2*string
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