# Why is there no isless(::Int64, ::UnitRange{Int64})?

**URL:** <https://discourse.julialang.org/t/why-is-there-no-isless-int64-unitrange-int64/112648>\
**Category:** General Usage\
**Tags:** range, unitrange\
**Created:** [April 7, 2024, 4:09pm UTC](https://discourse.julialang.org/t/why-is-there-no-isless-int64-unitrange-int64/112648 "2024-04-07T16:09:57Z")\
**Posts on this page:** 20\
**Page:** 2

<div class="post-metadata">

**Author:** ![mnemnion](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mnemnion/32/206596_2.png) [@mnemnion](https://discourse.julialang.org/u/mnemnion)\
**Post date:** [April 7, 2024, 7:59pm UTC](https://discourse.julialang.org/t/why-is-there-no-isless-int64-unitrange-int64/112648/21 "2024-04-07T19:59:26Z")

</div>

> [@dylanxyz](#):
>
> Or maybe:
> 
> ```julia
> julia> struct Interval{T <: Number}
> a::T
> b::T
> end
> 
> ```

This is the approach taken by Intervals.jl, yes.

```julia
julia> using Intervals

julia> 2 < 3..5
true

julia> 4 ≤ 3..5
false

```

Although it seems we don’t agree about the meaning of `≤` here.

It’s also missing some generic capabilities which would be critical given how I discovered the topic of this thread:

```julia
julia> "abcde"[2..3]
MethodError: no method matching getindex(::String, ::Interval{Int64, Closed, Closed})

```

That one might be worth a PR actually. Not clear if it’s in keeping with the spirit of the package, but it could be rather nice, I’ve wanted the ability to work with semi-open intervals fairly often when doing stringy things.

The question isn’t really about how to code around the lack of an `isless` here, that’s very straightforward.

I also want to point out that, as I mentioned in a previous post, `≤` defaults to `a < b || a ==b`. So defining `isless(i, range)` wouldn’t let slip the dogs of war.

---

<div class="post-metadata">

**Author:** ![mnemnion](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mnemnion/32/206596_2.png) [@mnemnion](https://discourse.julialang.org/u/mnemnion)\
**Post date:** [April 7, 2024, 8:05pm UTC](https://discourse.julialang.org/t/why-is-there-no-isless-int64-unitrange-int64/112648/22 "2024-04-07T20:05:14Z")

</div>

I’m willing to concede that my interpretation of `≤` is not obvious to everyone (that’s quite clear), so how about just this:

```julia
julia> Base.isless(i::Integer, r::UnitRange{<:Integer}) = i < r.start

julia> Base.isless(r::UnitRange{<:Integer}, i::Integer) = r.stop < i

julia> 2 < 3:5
true

julia> 6 > 3:5
true

julia> 4 ≤ 3:5
false

```

That seems hard to argue with as a meaningful result.

It would do some slightly perverse things with an empty range, but adding `isempty(r) ? false : ...` would sort that out.

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [April 7, 2024, 8:05pm UTC](https://discourse.julialang.org/t/why-is-there-no-isless-int64-unitrange-int64/112648/23 "2024-04-07T20:05:28Z")

</div>

> [@mnemnion](#):
>
> Although it seems we don’t agree about the meaning of `≤` here.

And there’s your answer as to why it’s not defined in Base.

Note that `1:3 == [1,2,3]` — ranges **are** vectors.

---

<div class="post-metadata">

**Author:** ![mnemnion](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mnemnion/32/206596_2.png) [@mnemnion](https://discourse.julialang.org/u/mnemnion)\
**Post date:** [April 7, 2024, 8:10pm UTC](https://discourse.julialang.org/t/why-is-there-no-isless-int64-unitrange-int64/112648/24 "2024-04-07T20:10:17Z")

</div>

> [@mbauman](#):
>
> And there’s your answer as to why it’s not defined in Base.

Well hold on a minute, I just demonstrated that defining `isless` doesn’t create the problematic equivalence relation!

> [@mbauman](#):
>
> Note that `1:3 == [1,2,3]` — ranges **are** vectors.

So I think that’s pretty strange, tbh. Why not this one then?

```julia
julia> "abc" == ['a', 'b', 'c']
false

```

After all:

```julia
julia> map(UInt8,['a', 'b', 'c'])
3-element Vector{UInt8}:
 0x61
 0x62
 0x63

julia> codeunits("abc")
3-element Base.CodeUnits{UInt8, String}:
 0x61
 0x62
 0x63

```

But I suspect the answer is “people find it useful, so we defined it that way”.

What’s the utility of `1 < 2:3` throwing an error?

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [April 7, 2024, 8:18pm UTC](https://discourse.julialang.org/t/why-is-there-no-isless-int64-unitrange-int64/112648/25 "2024-04-07T20:18:33Z")

</div>

Ranges are subtypes of AbstractVector. Strings aren’t. Yes, there are lots of alternate universes here that are equally-well founded. But these are choices that have already been made, and there’s not a consensus on what makes “obvious” sense in this universe as seen in the posts above.

---

<div class="post-metadata">

**Author:** ![mnemnion](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mnemnion/32/206596_2.png) [@mnemnion](https://discourse.julialang.org/u/mnemnion)\
**Post date:** [April 7, 2024, 8:29pm UTC](https://discourse.julialang.org/t/why-is-there-no-isless-int64-unitrange-int64/112648/26 "2024-04-07T20:29:44Z")

</div>

> [@mbauman](#):
>
> Ranges are subtypes of AbstractVector. Strings aren’t.

Fair enough. I could keep bickering about whether or not this is ideal, but I was looking for an explanation, and that suffices.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [April 7, 2024, 9:11pm UTC](https://discourse.julialang.org/t/why-is-there-no-isless-int64-unitrange-int64/112648/27 "2024-04-07T21:11:19Z")

</div>

> [@mbauman](#):
>
> Ranges are subtypes of AbstractVector. Strings aren’t.

(Note that `String` _cannot_ be a subtype of `AbstractVector`, even if we wanted this, because string iteration returns characters and characters cannot have consecutive indices with random access in the UTF-8 encoding — this would break the `AbstractVector` abstraction by either having non-consecutive indices or non-O(1) indexing. A [`codeunits(string)` view](https://docs.julialang.org/en/v1/base/strings/#Base.codeunits), on the other hand, _is_ a subtype of `AbstractVector`.)

---

<div class="post-metadata">

**Author:** ![jar1](https://avatars.discourse-cdn.com/v4/letter/j/c0e974/32.png) [@jar1](https://discourse.julialang.org/u/jar1)\
**Post date:** [April 7, 2024, 9:13pm UTC](https://discourse.julialang.org/t/why-is-there-no-isless-int64-unitrange-int64/112648/28 "2024-04-07T21:13:52Z")

</div>

Is it specified somewhere that iteration and indexing are in the same order for AbstractVector?

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [April 7, 2024, 9:31pm UTC](https://discourse.julialang.org/t/why-is-there-no-isless-int64-unitrange-int64/112648/29 "2024-04-07T21:31:54Z")

</div>

I don’t know if this is written down explicitly anywhere in the manual, but it should be — I think has always been understood that array iteration is equivalent to `eachindex` iteration (and in fact [is implemented this way](https://github.com/JuliaLang/julia/blob/c5a3b653353318607534fe9642c9e9476ff7d625/base/abstractarray.jl#L1230-L1234) for `AbstractArray`). (It’s [arguably implied](https://docs.julialang.org/en/v1/manual/arrays/#Iteration), at least.)

(Regardless, it _is_ documented that iteration (`for a in A`) yields the indexed elements `a[i]` of the array.)

Julia has never had a formal written specification ([DOC: language specification · Issue #4144 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/4144)), so there are a lot of things (like the array interface) that are mathematically underspecified by the documentation, but for which the behavior (as defined by the `julia` implementation) is not really a subject of debate.

---

<div class="post-metadata">

**Author:** ![danielwe](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/danielwe/32/35657_2.png) [@danielwe](https://discourse.julialang.org/u/danielwe)\
**Post date:** [April 8, 2024, 4:29am UTC](https://discourse.julialang.org/t/why-is-there-no-isless-int64-unitrange-int64/112648/30 "2024-04-08T04:29:08Z")

</div>

Possibly relevant: there’s an IEEE standard for interval arithmetic, [IEEE SA - IEEE 1788-2015](https://standards.ieee.org/ieee/1788/4431/), which is implemented by IntervalArithmetic.jl. See also the organization’s site at [https://juliaintervals.github.io/](https://juliaintervals.github.io/) for more context.

---

<div class="post-metadata">

**Author:** ![oxinabox](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oxinabox/32/206603_2.png) [@oxinabox](https://discourse.julialang.org/u/oxinabox)\
**Post date:** [April 8, 2024, 6:01am UTC](https://discourse.julialang.org/t/why-is-there-no-isless-int64-unitrange-int64/112648/31 "2024-04-08T06:01:44Z")

</div>

There is a nice Eric Lippet (a designer of C#) that he used to answer someone answer someone asking “Why doesn’t C# do x?”

which was that “Every feature starts at -100 points”.  
Meaning: not only does something have to be simply “good/useful” to be worth adding to the language/stdlib, it has to be substantially so.  
Because every feature adds complexity to both learning and maintaining, and takes time to implement.

---

<div class="post-metadata">

**Author:** ![TheLateKronos](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/thelatekronos/32/12824_2.png) [@TheLateKronos](https://discourse.julialang.org/u/TheLateKronos)\
**Post date:** [April 8, 2024, 7:04am UTC](https://discourse.julialang.org/t/why-is-there-no-isless-int64-unitrange-int64/112648/32 "2024-04-08T07:04:32Z")

</div>

I also feel like the sentiment in [On the arbitrariness of truth(iness)](https://discourse.julialang.org/t/on-the-arbitrariness-of-truth-iness/81381/56) applies here. And in much the same way Stefan concludes “Just say no to truthiness”, I would say “Just say no to (in)equality comparisons between numbers and collections of them.”

---

<div class="post-metadata">

**Author:** ![mnemnion](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mnemnion/32/206596_2.png) [@mnemnion](https://discourse.julialang.org/u/mnemnion)\
**Post date:** [April 8, 2024, 4:42pm UTC](https://discourse.julialang.org/t/why-is-there-no-isless-int64-unitrange-int64/112648/33 "2024-04-08T16:42:21Z")

</div>

> [@danielwe](#):
>
> Possibly relevant: there’s an IEEE standard for interval arithmetic, [IEEE SA - IEEE 1788-2015](https://standards.ieee.org/ieee/1788/4431/), which is implemented by [IntervalArithmetic.jl](https://juliahub.com/ui/Packages/General/IntervalArithmetic). See also the organization’s site at [https://juliaintervals.github.io/](https://juliaintervals.github.io/) for more context.

Interesting! I passed this on to a colleague who is building something which stands to take advantage of it. While accurate, it’s not especially ergonomic:

```julia
julia> 2 < 3..4
ArgumentError: `<` is purposely not supported for intervals. See instead `isstrictless`, `strictprecedes`

```

Fair enough, I’d like some operators though, Julia’s Unicode support makes a bunch available.

```julia
julia> isstrictless(3.0, 4..5)
MethodError: no method matching isstrictless(::Float64, ::Interval{Float64})

```

Well that’s annoying!

```julia
julia> isstrictless(convert(Interval{Float64},3.0), 4..5)
true

```

Seems like a DWIM moment to me…

> [@oxinabox](#):
>
> There is a nice Eric Lippet (a designer of C#) that he used to answer someone answer someone asking “Why doesn’t C# do x?”
> 
> which was that “Every feature starts at -100 points”.  
> Meaning: not only does something have to be simply “good/useful” to be worth adding to the language/stdlib, it has to be substantially so.

I’ve learned not to predict the outcome of this sort of post on Discourse, but I thought the mostly likely answer to my question was going to be “see issue `#xxxx`, especially [this comment]”. Which might still show up! But unless it does, it seems this particular question hasn’t had its day in the sun. (I did search the issue board before posting, but that means I checked a couple keywords, it certainly isn’t comprehensive).

An implementation for `isless(::Integer, UnitRange{<:Integer})` is a one-liner, implementation cost and maintenance burden are a non-issue here. Yes, a policy of “any one-liner is fine” results in a bloated and labyrinthine codebase, it still has to pull its weight. But if we’re starting at -100, “this is almost trivial” should be worth +50 at least.

I consider this the best argument against it:

```julia
julia> Base.isless(r::UnitRange{<:Integer}, i::Integer) = r.stop < i

julia> Base.isless(i::Integer, r::UnitRange{<:Integer}) = i < r.start

julia> 2 < 1:4
false

julia> 2 == 1:4
false

julia> 2 > 1:4
false

```

Although I would go up one level here, and say that where the documentation says:

> If isless(x, y) is defined, then so is isless(y, x) and isequal(x, y), and exactly one of those three yields true.

The more mathematically-sound interpretation of `<` is “at most one”, not “exactly one”. This does have implications for sorting: to sort a mixed collection of `<: Integer` and `UnitRange{<:Integer}`, one would have to supply an `lt` which determines which side of the fence `(2, 1:4)` should go on, or suffer an unstable sort.

But this, of course, reflects reality: `2 < 1:4` is decidedly `false`, but where one would put the two of them in a sort needs to choose another operation. IntervalArithmetic.jl makes it quite clear that sorting intervals and interval-like constructs takes resolution of several arbitrary degrees of freedom: how would you sort the pair `(2 ± 2, 2 ± 4)`?

The pragmatic construct which solves the issue in my codebase which prompted the question is simply `a < minimum(b)`, which works “correctly” for any Integer `a` and any of `Integer` or `UnitRange` `b`. The less practical answer would be to make some sort of ordering library with various operators. That would be cool but it isn’t on the short path to anything I want or need, so probably not.

> [@TheLateKronos](#):
>
> I also feel like the sentiment in [On the arbitrariness of truth(iness)](https://discourse.julialang.org/t/on-the-arbitrariness-of-truth-iness/81381/56) applies here. And in much the same way Stefan concludes “Just say no to truthiness”, I would say “Just say no to (in)equality comparisons between numbers and collections of them.”

I’ve worked with a lot of truthy languages, and my evaluation is a) Julia makes the right decision for Julia and b) Lua gets truthiness right. It’s a combination of factors. For one, only `false` and `nil` are falsey, everything else is truthy, and for another, accessing an unset field on a table returns `nil`, so `if haskey(table, :key)` may be spelled `if table.key`. Lua is a minimalist language, Julia is not. Slightly more cumbersome `if` clauses are worth the clarity it brings. `0` for false, in particular, is a lamentable confusion of levels which should only be available with a cast.

Which of course, Julia does provide:

```julia
julia> Bool(0)
false

julia> Bool(1)
true

```

The consensus I’m seeing is that, as a subtype of `AbstractVector`, a `UnitRange{T}` is primarily a minimal-allocation collection of values, rather than primarily what its struct would suggest, a `start` and a `stop` which describe a dense region of the ordering of `{T}`. Understandable, Julia’s community of practice is heavily array-oriented, and that is the supertype.

I view it as both of these things, and don’t consider “one shouldn’t pick an ordering relation between scalars and vectors” to be a slam-dunk argument against doing so for this particular vector. I would describe a `r::UnitRange{T}` as “The set or vector of all `t` in `T` for which `r.start ≤ t ≤ r.stop`”. I believe this is entirely correct.

I like to ask “how does this error help the user”?

```julia
julia> 4 < [2, 2, 2, 2, 2, 3, 7, 7, 128]
MethodError: no method matching isless(::Int64, ::Vector{Int64})

```

This error is helpful. Do you mean less than the minimum? less than the median? The mean? Was it just a mistake? Less than the first value because you know it’s sorted?

The same error for `4 < 6:8` seems less helpful to me. It could be a mistake, anything could be a mistake, but if it isn’t, you’ll note that all four suggested interpretations above give the same answer as I propose for `isless`. I would go so far as to claim that there is no interpretation of a `UnitRange` available in which `4 < 6:8` would be false. And it enables generic code for both an index and a dense region of indices, a privilege which needn’t be extended to the interpretation of `Vector{Int}` as a sparse collection of indices.

The digression surrounding `≤` at the beginning of this thread was unfortunate; while my interpretation is a sensible one, it’s at variance with the usual meaning of `≤` and is clearly confusing to most people. I withdraw the proposal.

I find it annoying for similar reasons that `copy` isn’t defined for immutable types. That error is useless, as is the branch which repairs it: “give me an independent version of this data” is operable on an immutable type, even though it happens to be “the same”. It makes things like using a macro to define a copy function for a mutable struct pointlessly difficult, the error isn’t helping the user.

My only dissatisfaction with `int < minimum(int_or_range)` is that it’s overly broad! It would “work” for a bunch of data types where I don’t intend the comparison to be meaningful. But then again, given that Julia has a type system, this issue can be completely avoided in all practical cases. So it will do.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [April 8, 2024, 5:13pm UTC](https://discourse.julialang.org/t/why-is-there-no-isless-int64-unitrange-int64/112648/34 "2024-04-08T17:13:29Z")

</div>

> [@mnemnion](#):
>
> it seems this particular question hasn’t had its day in the sun

Maybe. But note that with multiple dispatch, you can ask a practically infinite number of “why isn’t `f(::T, ::S)` defined?” questions, so this does not mean much.

One great thing about Julia Base (and most libraries) is that they did not err on the side of defining some arbitrary semantics just because they could. A `MethodError` is infinitely preferable to a silent bug.

---

<div class="post-metadata">

**Author:** ![mnemnion](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mnemnion/32/206596_2.png) [@mnemnion](https://discourse.julialang.org/u/mnemnion)\
**Post date:** [April 8, 2024, 5:37pm UTC](https://discourse.julialang.org/t/why-is-there-no-isless-int64-unitrange-int64/112648/35 "2024-04-08T17:37:18Z")

</div>

> [@Tamas\_Papp](#):
>
> Maybe. But note that with multiple dispatch, you can ask a practically infinite number of “why isn’t `f(::T, ::S)` defined?” questions, so this does not mean much.

It was an observation, certainly not a criticism. It matters whether this is a reboot of a settled question or whether it’s simply never been addressed before.

> [@Tamas\_Papp](#):
>
> One great thing about Julia Base (and most libraries) is that they did not err on the side of defining some arbitrary semantics just because they could. A `MethodError` is infinitely preferable to a silent bug.

True of course, but that comes back to my question “how is this error serving the user?”. No one wants Julia to arbitrarily pick semantics for every method in a misguided pursuit of full genericity. This is about one (two really) specific methods.

To summarize, the best argument for it is that `a::T < (b:c)::UnitRange{T}` would always be completely unambiguous and unsurprising. The best argument against it is that the manual has adopted “exactly one” semantics for `<`, and this has “at most one” semantics. To which my counter is that in mathematics, `<` is an at-most-one operation, and comparing a scalar value to an interval is only one of several cases where this is true.

One should note that [strict partial orders](https://en.wikipedia.org/w/index.php?title=Partially_ordered_set#strict_partial_order) use `<` without the requirement of [antisymmetry](https://en.wikipedia.org/wiki/Antisymmetric_relation), which is the “exactly one” I refer to in the documentation.

Colloquially, inequality doesn’t require equality to be a meaningful concept. Julia is overly strict here, when compared to notation.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [April 8, 2024, 5:46pm UTC](https://discourse.julialang.org/t/why-is-there-no-isless-int64-unitrange-int64/112648/36 "2024-04-08T17:46:54Z")

</div>

> [@mnemnion](#):
>
> quite clear that sorting intervals and interval-like constructs takes resolution of several arbitrary degrees of freedom

You keep talking about intervals, but there is no connection between vectors, like unit ranges, and intervals. If I were going to suggest a comparison that made a bit of sense it would be

```julia
<(x::Number, v::AbstractVector) = abs(x) < norm(v) 

```

or something along those lines.

---

<div class="post-metadata">

**Author:** ![danielwe](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/danielwe/32/35657_2.png) [@danielwe](https://discourse.julialang.org/u/danielwe)\
**Post date:** [April 8, 2024, 5:49pm UTC](https://discourse.julialang.org/t/why-is-there-no-isless-int64-unitrange-int64/112648/37 "2024-04-08T17:49:17Z")

</div>

> [@mnemnion](#):
>
> ```julia
> julia> isstrictless(3.0, 4..5)
> MethodError: no method matching isstrictless(::Float64, ::Interval{Float64})
> 
> ```
> 
> Well that’s annoying!

Perhaps they’d be receptive to a PR? Arithmetic operations promote, I don’t know if there’s any reason comparisons shouldn’t.

```julia
julia> x = 1.0 + (4.0..5.0)
[5.0, 6.0]_com_NG

julia> 2x
[10.0, 12.0]_com_NG

```

> [@mnemnion](#):
>
> where the documentation says:
> 
> > If isless(x, y) is defined, then so is isless(y, x) and isequal(x, y), and exactly one of those three yields true.
> 
> The more mathematically-sound interpretation of `<` is “at most one”, not “exactly one”.

Note that `isless` and `<` are different functions: `isless` should implement a total order, while `<` can implement a partial order (but falls back to `isless`). See [Mathematics · The Julia Language](https://docs.julialang.org/en/v1/base/math/#Base.:%3C:)

> New types with a canonical partial order should implement [[`<`](https://docs.julialang.org/en/v1/base/math/#Base.:%3C)] for two arguments of the new type. Types with a canonical total order should implement [`isless`](https://docs.julialang.org/en/v1/base/base/#Base.isless) instead.

---

<div class="post-metadata">

**Author:** ![mnemnion](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mnemnion/32/206596_2.png) [@mnemnion](https://discourse.julialang.org/u/mnemnion)\
**Post date:** [April 8, 2024, 5:53pm UTC](https://discourse.julialang.org/t/why-is-there-no-isless-int64-unitrange-int64/112648/38 "2024-04-08T17:53:33Z")

</div>

> [@danielwe](#):
>
> Note that `isless` and `<` are different functions: `isless` should implement a total order, while `<` can implement a partial order (but falls back to `isless`). See [Mathematics · The Julia Language](https://docs.julialang.org/en/v1/base/math/#Base.:%3C:)
> 
> > New types with a canonical partial order should implement [[`<`](https://docs.julialang.org/en/v1/base/math/#Base.:%3C)] for two arguments of the new type. Types with a canonical total order should implement [`isless`](https://docs.julialang.org/en/v1/base/base/#Base.isless) instead.

Great catch! I would say that puts the following on solid ground:

```julia
julia> Base.:<(i::Integer, r::UnitRange{<:Integer}) = i < r.start

julia> Base.:<(r::UnitRange{<:Integer}, i::Integer) = r.stop < i

```

It isn’t really debatable that this constitutes a valid partial order. I got thrown off by the special handling of `NaN` and managed to miss that, despite it being clearly stated in the documentation for both `isless` and `<`. Live and learn.

> [@danielwe](#):
>
> Perhaps they’d be receptive to a PR? Arithmetic operations promote, I don’t know if there’s any reason comparisons shouldn’t.

This is under discussion on a different channel 🙂 it isn’t really in my wheelhouse, but my comment probably came off sharper than intended.

---

<div class="post-metadata">

**Author:** ![o314](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/o314/32/252_2.png) [@o314](https://discourse.julialang.org/u/o314)\
**Post date:** [April 10, 2024, 1:46pm UTC](https://discourse.julialang.org/t/why-is-there-no-isless-int64-unitrange-int64/112648/39 "2024-04-10T13:46:04Z")

</div>

One should better consider things like

```julia
Base.all(f::F, r::AbstractRange) where {F<:Base.Fix2{typeof(<)}} = begin
    @assert ! isempty(r) # define me ! w trait dynamically according to r (currently), statically according to f ?!
    f(r[1])
end

using Test
@test all(<(3), 1:2)

```

and

```julia
for (fn,ind) in (
    (:(<),1),
    (:(>),2))
    # ...
    @eval Base.all(f::F, r::AbstractRange) where {F<:Base.Fix2{typeof($fn)}} = begin
        @assert ! isempty(r) # idem
        f(r[$ind])
    end
end

using Test
@test all(<(3), 1:2)
@test all(>(1), 2:3)

```

---

<div class="post-metadata">

**Author:** ![mkitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkitti/32/12459_2.png) [@mkitti](https://discourse.julialang.org/u/mkitti)\
**Post date:** [April 10, 2024, 1:59pm UTC](https://discourse.julialang.org/t/why-is-there-no-isless-int64-unitrange-int64/112648/40 "2024-04-10T13:59:34Z")

</div>

A new definition of `all` is not needed. That already works, does it not?

```julia
$ julia -E "all(<(3), 1:2)"
true

```

[Previous page](https://discourse.julialang.org/t/why-is-there-no-isless-int64-unitrange-int64/112648.md?page=1)

[Next page](https://discourse.julialang.org/t/why-is-there-no-isless-int64-unitrange-int64/112648.md?page=3)
