PARAM tuples

Are there plans to have a param tuple?

As it stands, complex(w) is the only numeric type which cannot be a param.

Just curious.

Was there a discussion about this previously or am I imagining things?


Hi @damianmoz & happy new year.

A complex can be param, for example, this program creates a param complex and includes it in a compilation warning:

param x = 1.25i + 3.25;

compilerWarning("I have a param complex: ", x:string);

However, if you have observed that some code working with complex numbers can't keep it all param, it is somewhat likely that there are some operations on complex that could produce a param but lose the param-ness today. If you run into such a case, it will help if you can make a github issue about it specifically.

In the long term, I think we would like to allow param tuples and param records, but I don't know of any plans to add these in the near term.

1 Like

Ah, based on your other issues, I see that at least abs is something you would expect for a param complex number but it is not available. Presumably sqrt is in the same category (but I did not check). I made an issue about the abs case: feature request: abs for param complex · Issue #24125 · chapel-lang/chapel · GitHub .

Adding sqrt is definitely a lot harder. But that would be nice and highlights the power of the language.

Mind you, once you do that, the need for definitions of params like sqrt_2 disappear, cleaning things up and simplifying things. Such a feature allows you to write

sqrt(2.0) // to get the equivalent of sqrt_2 or even

knowing that it has no run-time overhead. At the highest level of warnings, the compiler should mention that such a computation is done subject to the rounding in effect at compile time, not that in effect at that point in the program at run-time. You need that same message to appear in a verbose warning mode when computing the magnitude of a complex number at compile time.

But again, no urgency.

My original desire across the Christmas break for a param tuple came about from doing code like

param zero = 0:real(w);
param inf = Inf(real(w));
var (tmax, tmin) = (zero, inf);

in multiple places in a program and a desire to simplify it to just

param zeroinf = (zero, inf);
var (tmax, tmin) = zeroinf;

This is actually part of the more general issue raised in #23431 on Github for param compound types that I could not find last week when I posted this thing.

As an aside, there are limitations of a definition like

param x = 1.25i + 5.0;

because that only provides a complex(128). There is no way to produce a param complex(64) from two separate real(32) param identifiers unless they are real(64) literals like:

param x = (1.25i + 5.0):complex(64);

But the solution to that is the solution of #23431.

Hi Damian —

I don't think that's accurate. Adding or subtracting 32-bit param values of mixed real/imag type should also result in a param complex(64). Here's an example that demonstrates that (ATO):

param a = 1.25i: imag(32);
param b = 5.0: real(32);

testVal(1.25i:imag(32) + 5.0: real(32));
testVal((1.25i + 5.0): complex(64));
testVal(a + b);

proc testVal(param x) {
  writeln("got param ", x, ": ", x.type:string);

proc testVal(x) {
  writeln("got non-param ", x, ": ", x.type:string);

Do you have other examples you can share that illustrate cases that didn't work as expected?


Fascinating. I had not thought of the approach of using an imag(w).

My brain was still stuck in the C mindset of a compile time

static const float complex y = 1.0f + 6.0f * I;

Also, I had forgotten that I had already submitted #23431 which already has the original question, i.e. the ability to define

param zeroinf - (0.0, INFINITY);

So, the request is already in the Github pipeline.

1 Like