# Tuples of ranges

Why can I have a tuple of ranges which have the same stride but not, as below, a tuple of ranges which have different strides.

``````// computea matrix's cross diagonal waves, the ranges
// which go from the bottom left to the top right

proc crossDiagonalWave(rMax : int, cMax : int)
{
param rmin = 2, cmin = 2;
const rmax = rMax - 1, cmax = cMax -1;
var isiz = 1, siz : [1..rmax + cmax-3] (range, range);

// process a cross (semi-)diagonal - bottom left to upper right

proc wave(_r : int, _c : int)
{
var r = _r, c = _c;

while c >= cmin && r <= rmax do
{
r += 1;
c -= 1;
}
return (_r .. r - 1, c + 1 .. _c by -1);
}

assert(rMax > rmin && cMax > cmin);

siz[isiz] = (rmin..rmin, cmin..cmin by -1);

for c in cmin + 1 .. cmax do // process above the cross diagonal
{
isiz += 1; siz[isiz] = wave(rmin, c);
}
for r in rmin + 1 .. rmax do // process below the cross diagonal
{
isiz += 1; siz[isiz] = wave(r, cmax);
}
return siz;
}
``````

What have I done wrong?

Hello Damian,

Maybe the issue is not in the tuple? The following compiles and runs for me:

``````proc wave(_r : int, _c : int)
{
var r = _r, c = _c;

while c >= 10 && r <= 0 do
{
r += 1;
c -= 1;
}
return (_r .. r - 1, c + 1 .. _c by -1);
}

writeln(wave(1,1));
``````

The clause in your while loop would be a No-Op. But, even when I use it, I get:

``````front.chpl:4: In function 'periDiagonalWave':
front.chpl:26: error: type mismatch in assignment of ranges with different stridable parameters
``````

Here is the complete code which fails. I am using a special version of 1.28.0 from Brad. The special mods have nothing to do with ranges. They just allow me to see the underlying hexadecimal unsigned integral value inside a floating point parameter. So, it should look like standard 1.28.0 compiler for our purposes here. Maybe I should try it with 1.30.0 next week.

``````// compute matrix's cross diagonal waves, the ranges
// which go from the bottom left to the top right

proc periDiagonalWave(rMax : int, cMax : int)
{
param rmin = 2, cmin = 2;
const rmax = rMax - 1, cmax = cMax -1;
var isiz = 1, siz : [1..rmax + cmax-3] (range, range);

// process a cross (semi-)diagonal - bottom left to upper right

proc wave(_r : int, _c : int)
{
var r = _r, c = _c;

while c >= cmin && r <= rmax do
{
r += 1;
c -= 1;
}
return (_r .. r - 1, c + 1 .. _c by -1);
}

assert(rMax > rmin && cMax > cmin);

siz[isiz] = (rmin..rmin, cmin..cmin by -1);

for c in cmin + 1 .. cmax do // process above the cross diagonal
{
isiz += 1; siz[isiz] = wave(rmin, c);
}
for r in rmin + 1 .. rmax do // process below the cross diagonal
{
isiz += 1; siz[isiz] = wave(r, cmax);
}
return siz;
}

config const c = 10;
config const r = 10;

proc main
{
writeln("TRY ", r, ",", c);

const rcpairs = periDiagonalWave(r, c);
const size = c + r - 5;

for (rows, columns) in rcpairs do
{
write(' next ');
for (r, c) in zip(rows, columns by -1) do
{
write(' (', r, ',', c, ')');
}
writeln('|');
}
writeln('Size ', rcpairs.domain);
return 0;
}
``````

The fix is in the type definition

`````` var isiz = 1, siz : [1..rmax + cmax-3] (range, range(stridable=true));
``````

Once I do this, I can then use a stridable range as the second component of the tuple.

Sorry. I will switch my brain on next time. Silly me.

Me too. I missed the scrollbar in your original code.

Glad you fixed the issue. Also we are intending to have the compiler issue a hint in cases like this.

Vass