
On Fri, Aug 05, 2016 at 12:09:09PM +0900, Stephen J. Turnbull wrote:
Steven D'Aprano writes:
clamp(x, y, z) --> NaN if z < y
That's a clear error, and it should raise immediately. I see no advantage to returning NAN in this case.
Think about why you're clamping. It's unlikely to be used just once, for a single calculation. You're likely to be clamping a whole series of values, with a fixed lower and upper bounds.
"Likely" isn't a good enough reason:
Of course it is. We write code to prefer known, common use-cases, not just hypothetical "What If" scenarios. E.g. most trig functions (sin, cos, tan) take angles in radians. I've seen a few take angles in degrees. I've even seen trig functions that take their argument as a multiple of pi (e.g. sinpi(1.25) being equivalent to sin(1.25*pi), only more accurate). All of these have good use-cases. But I'm willing to bet that you will never, ever find a general purpose programming language or maths library with specialised trig functions that take arguments in 1/37th of a gon. (Yes, "gon" is a real unit.) If you need such a thing, you write it yourself. Chris has already gone through his code and confirmed what I expected: he uses "clamp" extensively, and the bounds are invariably fixed once at the start of the loop. But if you find yourself in that unusual situation of needing something unusual, you can easily write your own wrapper: def clamp(value, lower, upper): if lower > upper: return "Surprise!" return math.clamp(value, lower, upper) Of course, if math.clamp() returned NAN, you could just as easily go the other way and write a wrapper to raise instead. Neither case is particularly onerous. But in one case, only a few people will need to wrap the function; in the second case, many people (possibly even *everybody*) will want to wrap the function to avoid the unhelpful standard behaviour. It is our job as function designers to try to cater for the majority, not the minority, when possible.
x = [clamp(x[t], f(t), g(t)) for t in range(1_000_000)]
is perfectly plausible code.
I have my doubts. Sure, you can write it, but what would you use it for? What's your use-case? -- Steve