On Sun, Jul 5, 2020 at 6:01 PM Greg Ewing
On 6/07/20 3:55 am, Steven D'Aprano wrote:
With that interpretation, a NAN passed as the lower or upper bounds can be seen as another way of saying "no lower bounds" (i.e. negative infinity) or "no upper bounds" (i.e. positive infinity), not "some unknown bounds".
Python already has a value for representing missing or unspecified data, i.e. None. So we don't need to use NaN for that, and can instead reserve it to mean "no correct answer".
+1 and we can use +inf and -inf for unlimited bounds as well. Yes, they are a bit of a pain to write in Python, but we could do: def clamp(value, min=-math.inf, max=math.inf): ... yes, that would make them optional, rather than required, and therefore provide a slight asymmetry between specifying min only or max only, but still be handy. to make it more consistent, but maybe more annoying in the common case, we could make them keyword only.
I agree with you that `clamp(lower=x, value=NAN, upper= x)` should
return x.
I don't think I agree with that, because it relies on assuming that the lower and upper bounds can meaningfully be compared for exact equality, which may not be true depending on the circumstances.
and then we'd need to check if they were equal as well.
Treat a NAN bounds as *missing data*, which effectively means "there is no limit", i.e. as if you had passed the infinity of the appropriate sign for the bounds.
and really how often would one end up with NaN as a bound anyway? Often
they will be hard-coded. I"m having a really hard time imagining when you'd
end up with NaN for a bound that was NOT an error!
It would be far more likely for the value you want clamped to be NaN -- and
then it sure as heck should return NaN.
As for the behavior of min() and max() when provided a NaN (and much of
Python's handling of FP special values) -- I think that's a
practicality-beats-purity issue. I have a really hard time thinking that
anyone thinks that:
In [81]: min(1, math.nan)
Out[81]: 1
In [82]: min(math.nan, 1)
Out[82]: nan
is ideal behavior!
while I was writing this:
On Sun, Jul 5, 2020 at 6:38 PM Steven D'Aprano
... on this point at least the IEEE-754 standard is firm: if a function will return the same result for every non-NAN argument, then it must return the same result for NAN arguments too.
clamp(value, x, x)
will always return x for every finite and infinite value, so it must return x for NANs too.
Except that Python (maybe except for the math module) does not conform to IEEE-754 in many other places. So we do have a practicality beats purity choice here. -CHB -- Christopher Barker, PhD Python Language Consulting - Teaching - Scientific Software Development - Desktop GUI and Web Development - wxPython, numpy, scipy, Cython