Basics.clamp doesn't passthrough NaN
malaire opened this issue · 2 comments
If clamp is given NaN as third argument it should return it unchanged, but instead it returns the given upper limit:
elm repl
> clamp -100 100 (0/0)
100 : Float
I don't understand why this happens. clamp is defined as (source)
clamp : number -> number -> number -> number
clamp low high number =
if lt number low then
low
else if gt number high then
high
else
number
Since both comparisons should be False, number should be returned unchanged, but that doesn't happen.
I can't test gt myself, but its corresponding > does return False as expected:
elm repl
> (0/0) > 100
False : Bool
Maybe related to #1050
Thanks for reporting this! To set expectations:
- Issues are reviewed in batches, so it can take some time to get a response.
- Ask questions a community forum. You will get an answer quicker that way!
- If you experience something similar, open a new issue. We like duplicates.
Finally, please be patient with the core team. They are trying their best with limited resources.
Basics.clamp is compiled to:
var $elm$core$Basics$clamp = F3(
function (low, high, number) {
return (_Utils_cmp(number, low) < 0) ? low : ((_Utils_cmp(number, high) > 0) ? high : number);
});
and because _Utils_cmp does:
function _Utils_cmp(x, y, ord)
{
if (typeof x !== 'object')
{
return x === y ? /*EQ*/ 0 : x < y ? /*LT*/ -1 : /*GT*/ 1;
}
with both x === y and x < y returning false with NaN, it will return GT, therefore the clamp higher value will be returned:
> Basics.compare (0/0) 100
GT : Order
(>) (0/0) 100 returns False because it is optimized by the compiler to (0 / 0) > 100 in javascript without using _Utils_cmp.
If you trick the compiler to avoid the optimization, you get True for NaN > 100:
> (>) (0/0) 100
False : Bool
> gt = (>)
<function> : comparable -> comparable -> Bool
> gt (0/0) 100
True : Bool