Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Tuple Concatenation in Chapel

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!!

like image 613
Tshimanga Avatar asked Jan 26 '18 00:01

Tshimanga


1 Answers

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
like image 180
Brad Avatar answered Oct 25 '22 22:10

Brad