On Fri, Aug 12, 2016 at 4:25 PM, Victor Stinner firstname.lastname@example.org wrote:
I tried to follow this discussion and I still to understand why my proposition of "def clamp(min_val, value, max_val): return min(max(min_val, value), max_val)" is not good. I expect that a PEP replies to this question without to read the whole thread :-) I don't recall neither what was the "conclusion" for NaN.
This was the implementation I suggested (but I borrowed it from StackOverflow, I don't claim originality). There are a couple arguable bugs in that implementation, and several questions I would want answered in a PEP. I'm not going to argue again about the best answer, but we should explicitly answer what the result of the following are (with some justified reasons):
clamp(5, nan, nan) clamp(5, 0, nan) clamp(5, nan, 10) clamp(nan, 0, 10) clamp(nan, 5, 5)
Also, min and max take the "first thing not greater/less than the rest". Arguably that's not what we would want for clamp(). But maybe it is, explain the reasons. E.g.:
This has the obvious implications for the semantics of clamp() if it is based on min()/max() in the manner proposed.
Also, what is the calling syntax? Are the arguments strictly positional, or do they have keywords? What are those default values if the arguments are not specified for either or both of min_val/max_val? E.g., is this OK:
If this is allowable to mean "unbounded on the top" then the simple implementation will break using the most obvious default values:
clamp('foo', min_val='aaa') # expect "lexical clamping"
min(max("aaa", "foo"), float('inf'))
Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unorderable types: float() < str()
min(max("aaa", "foo"), None)
Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unorderable types: NoneType() < str()
min(max("aaa", "foo"), "zzz")
Quite possibly this is exactly the behavior we want, but I'd like an explanation for why.