On Sat, Jul 04, 2020 at 10:16:45AM +0200, Federico Salerno wrote:

> Yes, I'd expect ValueError if min > max or max < min.

Is there a difference between those two conditions? *wink*


> On 04/07/2020 02:03, Steven D'Aprano wrote:
> >Bottom line is that passing a NAN as the lower or upper bound should 
> >treat it as equivalent to "unbounded", that is, equivalent to ±∞. The 
> >beauty of that is that it can be implemented without explicitly 
> >testing for NANs, which involves unnecessary conversions to float, and 
> >may even raise an exception. Here is the version I use: ... Features: 
> >* uses None as a convenient alias for unbounded; * treats NANs 
> >according to the standard; * requires no explicit conversion to float 
> >or testing for NANs; * so this will work with Fractions and Decimals.
> 
> I'm not opposed to this but wouldn't the programmer expect it to behave 
> much like a shorthand of the existing min() + max()?

For regular numeric numbers, it does.

The only differences I can see are that my implementation of clamp() 
supports None as a short-hand for infinity; and that it treats NANs 
according to the standard, unlike the builtin min and max, which manage 
to provide the worst of both possible words: they treat NANs according 
to the order of the arguments, thus satisfying nobody and annoying 
everybody.

The first part is, I think, important because with the min+max idiom, if 
one side is unbounded, you can just leave it out:

    min(x, 1000)  # like clamp(x, -float('inf'), 1000)

but with clamp you have to supply *something* to mean "unbounded", and 
using float("inf") is not very convenient. So it's just a tiny bit of 
sugar to make the function more useful.

I've been using it for about four years, and it's nice to have. Having a 
short-cut for clamp is a good usability feature that costs very little 
(a couple of extra pointer comparisons to test for `is None`, which is 
cheap as it comes in Python).


> Should these two 
> then be modified to exhibit the same behaviour? I'd find it inconsistent 
> if clamp() did but min() and max() didn't.

Perhaps you should reconsider your expectations there. They do different 
things because they are different functions with different signatures 
and different purposes. It isn't even necessary to use min and max in 
the implementation of clamp, in fact it is better not to.

Any "consistency" arguments for clamp versus min/max are weak at best.



-- 
Steven
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/6SLKNXMFPIH2UMR3SBQP7H2B7QXCYMUN/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to