That means that the default lt = isless
would be wrong, since it would give issorted([1, 1]) == false
.
You could then suggest the default be lt = <=
, but note that the fallback for <=
is defined in terms of <
:
And <
is defined in terms of isless
:
If you simply define isless
and ==
(EDIT: not isequal
), you get the desired (probably) definitions of the other operators. I’d say that this is nothing more than a design choice, but it’s one that works pretty well in my opinion. And indeed you can write issorted
in terms of isless
: instead of checking that every consecutive element satisfies a property, you instead check that no consecutive element violates a property.
I understand that this extra negation and swapping of the arguments is not the first definition of issorted
that some people are thinking of. But the definition that is in Base
is self-consistent. That’s not to say that this can’t be better documented.
I’ll add that there might be cases where it’s better to define isless
on your type (possible a wrapper type) than it is to pass in a function for lt
. I asked about these two choices once upon a time: Designing APIs. defining new methods versus passing in functions