Hi Damian —
Michael beat me to this by a few minutes, but here are a few other notes pertaining to the original expression:
Normally, when you want to have two arguments with the same width, you wouldn't unify them to the same w
using two ?w
queries (which, as Chapel is defined today, would define two instances of the same w
identifier within the same scope, which should generate an error); instead, you would query one or both and assert the other is the same using one of a few approaches:
The first is to query the first argument's width and constrain the second's to be the same:
inline proc cmplx(x: real(?w) , y: imag(w)) {
return x * exp(y);
}
The other is to query the widths of both and assert that they match:
inline proc cmplx(x: real(?w) , y: imag(?w2)) where w == w2 {
return x * exp(y);
}
The subtle difference between these is that if the first argument was a real(64)
, say, the first expression would be like declaring:
inline proc cmplx(x: real(64) , y: imag(64)) {
return x * exp(y);
}
which would mean that you could pass anything to y
that could be passed to an imag(64)
, including an imag(32)
.
In contrast, passing a real(64)
to the second approach ought to require the second argument to be an imag(64)
as well:
inline proc cmplx(x: real(64) , y: imag(?w2)) where 64 == w2 {
return x * exp(y);
}
In which case an imag(32)
y
argument would not be legal.
Note, however, that in Chapel 1.31 and earlier, this version of the routine would actually accept imag(32)
without warning because we proactively interpreted any built-in scalar argument type of the form t(?w)
as meaning "Stamp out a version of this routine for all legal forms of t(w)
." As a result, one of the overloads we'd stamp out would be:
inline proc cmplx(x: real(64) , y: imag(64) where 64 == 64 {
return x * exp(y);
}
and this version would be called.
This behavior is the same in Chapel 1.32, but now generates a warning to indicate that in future releases we'll be changing the behavior to match what I've described above. I.e., passing in a real(64) and imag(32) would correspond to this call:
inline proc cmplx(x: real(64) , y: imag(32) where 64 == 32 {
return x * exp(y);
}
which would not resolve due to the where-clause being false
.
Today, unfortunately, the way to get this behavior would be to explicitly stamp out the two overloads you want manually:
inline proc cmplx(x: real(32) , y: imag(32) {
return x * exp(y);
}
inline proc cmplx(x: real(64) , y: imag(64) {
return x * exp(y);
}
Hope this is clear and makes sense,
-Brad