One could argue that:
Is clearly defined as x. But that would require special casing
Not so special:
if lower == upper != None: return lower
I had the impression earlier that you didn't want a whole pile of special cases, even if each was simple. But sure, this is a nice one to get "right".
on a NAN will lead to a non-NAN:
Yes, if you'd get the same non-nan result for any floating point value where the NaN is, then that makes sense - if NaN means "we have no idea what value this is", but you get the same result regardless, then fine.
But that does Not apply to:
clamp(x, y, Nan)
Or min(x NaN)
However, as wrong as I might think it is ( ;-) ) -- it seems the IEEE has decided that:
min(x, NaN) should truth x (and max).
So we should be consistent.
Arithmetic operations upon NaNs ... never signal INVALID, and always produce NaN unless replacing every NaN operand by any finite or infinite real values would produce the same finite or infinite floating-point result independent of the replacements.
Which is the case for:
But is not for;
clamp(x, NaN, NaN)
But a standard is a standard :-(