# \`\<=\` does not desugar correctly with custom struct

**URL:** <https://discourse.julialang.org/t/does-not-desugar-correctly-with-custom-struct/62570>\
**Category:** General Usage\
**Created:** [June 8, 2021, 9:51am UTC](https://discourse.julialang.org/t/does-not-desugar-correctly-with-custom-struct/62570 "2021-06-08T09:51:28Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Samuel\_Ainsworth](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/samuel_ainsworth/32/15644_2.png) [@Samuel\_Ainsworth](https://discourse.julialang.org/u/Samuel_Ainsworth)\
**Post date:** [June 8, 2021, 9:51am UTC](https://discourse.julialang.org/t/does-not-desugar-correctly-with-custom-struct/62570/1 "2021-06-08T09:51:28Z")

</div>

So I have a bit of code:

```julia
struct Foo
  val::Float64
end
@show 0.0 <= Foo(0.0)

```

but then `MethodError: no method matching isless(::Float64, ::Foo)`. Oh right, I forgot to define `isless`:

```julia
struct Foo
  val::Float64
end
function Base.isless(lhs::Float64, rhs::Foo)
  Base.isless(lhs, rhs.val)
end
@show 0.0 <= Foo(0.0) # this prints false!

```

Wait what… how is this possible? But 0.0 \<= 0.0!

Does anyone have any idea what’s going on here? This strikes me as a bug.

---

<div class="post-metadata">

**Author:** ![sijo](https://avatars.discourse-cdn.com/v4/letter/s/da6949/32.png) [@sijo](https://discourse.julialang.org/u/sijo)\
**Post date:** [June 8, 2021, 9:58am UTC](https://discourse.julialang.org/t/does-not-desugar-correctly-with-custom-struct/62570/2 "2021-06-08T09:58:44Z")

</div>

The documentation for `<=` says

> Less-than-or-equals comparison operator. Falls back to `(x < y) | (x == y)`.

In your case, `x < y` returns false as expected, but `x == y` also returns false because as the documentation says

> Generic equality operator. Falls back to `===`. Should be implemented for all types with a notion of equality, based on the abstract value that an instance represents.  
> […]  
> New numeric types should implement this function for two arguments of the new type, and handle comparison to other types via promotion rules where possible.

So you need to implement `==`, otherwise the default `===` is used which returns false in this case.

---

<div class="post-metadata">

**Author:** ![Samuel\_Ainsworth](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/samuel_ainsworth/32/15644_2.png) [@Samuel\_Ainsworth](https://discourse.julialang.org/u/Samuel_Ainsworth)\
**Post date:** [June 8, 2021, 10:01am UTC](https://discourse.julialang.org/t/does-not-desugar-correctly-with-custom-struct/62570/3 "2021-06-08T10:01:44Z")

</div>

Thanks so much! This solves my problem, but I’d just like to note that the overall experience defining these operators is still quite confusing, esp. understanding which ones are required in order to get reasonable behavior.

In my case, I had tried defining `isequal` but not `==`. I was (mistakenly) under the impression that these were equivalent.

---

<div class="post-metadata">

**Author:** ![sijo](https://avatars.discourse-cdn.com/v4/letter/s/da6949/32.png) [@sijo](https://discourse.julialang.org/u/sijo)\
**Post date:** [June 8, 2021, 10:11am UTC](https://discourse.julialang.org/t/does-not-desugar-correctly-with-custom-struct/62570/4 "2021-06-08T10:11:22Z")

</div>

You’re welcome! Each of these operators/functions has an “Implementation” section in the documentation that says what should be implemented in which case, but I agree it’s a bit confusing.

---

<div class="post-metadata">

**Author:** ![Samuel\_Ainsworth](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/samuel_ainsworth/32/15644_2.png) [@Samuel\_Ainsworth](https://discourse.julialang.org/u/Samuel_Ainsworth)\
**Post date:** [June 9, 2021, 5:18am UTC](https://discourse.julialang.org/t/does-not-desugar-correctly-with-custom-struct/62570/5 "2021-06-09T05:18:51Z")

</div>

> [@sijo](#):
>
> Less-than-or-equals comparison operator. Falls back to `(x < y) | (x == y)` .

Btw, why `(x < y) | (x == y)` and not `(x < y) || (x == y)`? Seems like there’s no harm in short-circuiting?
