# How to overload operators and their doc bindings

**URL:** <https://discourse.julialang.org/t/how-to-overload-operators-and-their-doc-bindings/87372>\
**Category:** General Usage\
**Created:** [September 16, 2022, 2:07pm UTC](https://discourse.julialang.org/t/how-to-overload-operators-and-their-doc-bindings/87372 "2022-09-16T14:07:16Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![uje](https://avatars.discourse-cdn.com/v4/letter/u/5f9b8f/32.png) [@uje](https://discourse.julialang.org/u/uje)\
**Post date:** [September 16, 2022, 2:07pm UTC](https://discourse.julialang.org/t/how-to-overload-operators-and-their-doc-bindings/87372/1 "2022-09-16T14:07:16Z")

</div>

```julia
julia> module Foo
           struct Point
               x::Int
               y::Int
           end
           
           """
               <(a::Point, b::Point) -> Bool
               
           Compare two `Point`s object.
           """
           function <(a::Point, b::Point)
               a.x < b.x || a.y < b.y || (a.x == b.x) && (a.y < b.y)
           end
       end
Main.Foo

help?> Foo.<
search:

Couldn't find Foo.<
Perhaps you meant Foo, Bool or floor
  No documentation found.

  Binding Foo.< does not exist.

help?> Foo.:<
  <(a::Point, b::Point) -> Bool

  Compare two Points object.

```

Isn’t there a way to define this, so its called with `Foo.<` as the normal method would have been and not `Foo.<`?

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [September 16, 2022, 2:43pm UTC](https://discourse.julialang.org/t/how-to-overload-operators-and-their-doc-bindings/87372/3 "2022-09-16T14:43:31Z")

</div>

Note that the help does not work even with the standard `<`:

```julia
help?> Main.<
search:

Couldn't find Main.<
Perhaps you meant Main or Matrix
  No documentation found.

  Binding Main.< does not exist.

```

Thus, not answering exactly that question, there are two things: Using `Foo.<` as as that would be very inconvenient if you do not export `<` from your module.

Yet, if you want to export it, you are probably wanting to overload the `Base.<`, and in that case you should that explicitly:

```julia
julia> module Foo
          
           struct Point
               x::Int
               y::Int
           end
           
           import Base: < # import here
           """
               <(a::Point, b::Point) -> Bool
               
           Compare two `Point`s object.
           """
           function <(a::Point, b::Point)
               a.x < b.x || a.y < b.y || (a.x == b.x) && (a.y < b.y)
           end
       end
WARNING: replacing module Foo.
Main.Foo

```

with which `<` works for your points:

```julia
julia> x = Foo.Point(1,1); y = Foo.Point(2,2);

julia> x < y
true

```

and the help entry appears when typing `? <` (among the other definitions for `<`):

```julia

  <(a::Point, b::Point) -> Bool

  Compare two Points object.

```

---

<div class="post-metadata">

**Author:** ![uje](https://avatars.discourse-cdn.com/v4/letter/u/5f9b8f/32.png) [@uje](https://discourse.julialang.org/u/uje)\
**Post date:** [September 16, 2022, 2:48pm UTC](https://discourse.julialang.org/t/how-to-overload-operators-and-their-doc-bindings/87372/4 "2022-09-16T14:48:19Z")

</div>

Thank you.

But the issue here is that I don’t want other definitions for `<` showing except the one I defined. That’s what I’m trying to solve.

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [September 16, 2022, 2:52pm UTC](https://discourse.julialang.org/t/how-to-overload-operators-and-their-doc-bindings/87372/5 "2022-09-16T14:52:50Z")

</div>

Yeah, I do not think you can do that right now. It seems a very specific parsing issue the fact that the `help>` prompt is not able to show `Base.<` or similar entries.

But be careful that, in your case, you didn’t overload the `Base.<` operator, you defined a new one, and inside your module `<` won’t work anymore for any other type except the ones you defined (note that your example **does not work** , but you don’t have `<` defined anymore for integers, thus your `Foo.<` function errors).

---

<div class="post-metadata">

**Author:** ![uje](https://avatars.discourse-cdn.com/v4/letter/u/5f9b8f/32.png) [@uje](https://discourse.julialang.org/u/uje)\
**Post date:** [September 16, 2022, 2:54pm UTC](https://discourse.julialang.org/t/how-to-overload-operators-and-their-doc-bindings/87372/6 "2022-09-16T14:54:27Z")

</div>

Yeah I’m aware. My main issue is the docs bindings, I just wrote a dummy function to test it

I’m experimenting with some stuffs and I don’t want the other docs to show up in the `help` section

---

<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:** [September 16, 2022, 3:40pm UTC](https://discourse.julialang.org/t/how-to-overload-operators-and-their-doc-bindings/87372/7 "2022-09-16T15:40:44Z")

</div>

> [@lmiq](#):
>
> Note that the help does not work even with the standard `<`:
> 
> ```julia
> help?> Main.<
> search:
> 
> Couldn't find Main.<
> 
> ```

You often need to quote ([as `:symbol`](https://docs.julialang.org/en/v1/manual/metaprogramming/#Symbols)) special symbols like `<` when qualifying them:

```julia
help?> Main.:<
  <(x, y)

  Less-than comparison operator. Falls back to isless. Because of the behavior
  of floating-point NaN values, this operator implements a partial order.

```

---

<div class="post-metadata">

**Author:** ![uje](https://avatars.discourse-cdn.com/v4/letter/u/5f9b8f/32.png) [@uje](https://discourse.julialang.org/u/uje)\
**Post date:** [September 16, 2022, 3:42pm UTC](https://discourse.julialang.org/t/how-to-overload-operators-and-their-doc-bindings/87372/8 "2022-09-16T15:42:47Z")

</div>

So there’s virtually no way to solve the problem posed at hand?

---

<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:** [September 16, 2022, 3:43pm UTC](https://discourse.julialang.org/t/how-to-overload-operators-and-their-doc-bindings/87372/9 "2022-09-16T15:43:34Z")

</div>

Works fine for me with quoting:

```julia
help?> Foo.:<
  <(a::Point, b::Point) -> Bool

  Compare two Points object.

```

---

<div class="post-metadata">

**Author:** ![uje](https://avatars.discourse-cdn.com/v4/letter/u/5f9b8f/32.png) [@uje](https://discourse.julialang.org/u/uje)\
**Post date:** [September 16, 2022, 3:44pm UTC](https://discourse.julialang.org/t/how-to-overload-operators-and-their-doc-bindings/87372/10 "2022-09-16T15:44:39Z")

</div>

But then how you quote it when it has to do with `::` operators.

This is the problem. Operators or functionality with the `:` in their makeup won’t work well or it will mess up things.

---

<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:** [September 16, 2022, 3:46pm UTC](https://discourse.julialang.org/t/how-to-overload-operators-and-their-doc-bindings/87372/11 "2022-09-16T15:46:34Z")

</div>

> [@uje](#):
>
> But then how you quote it when it has to do with `::` operators.

`::` is not an ordinary operator and cannot be overloaded; it is a syntactic keyword.

But in general you can use parentheses along with quoting to disambiguate the parsing:

```julia
help?> Main.:(:)
  (:)(start, [step], stop)

  Range operator. a:b constructs a range from a to b with a step size of 1 (a
  UnitRange) , and a:s:b is similar but uses a step size of s (a StepRange).

```

---

<div class="post-metadata">

**Author:** ![uje](https://avatars.discourse-cdn.com/v4/letter/u/5f9b8f/32.png) [@uje](https://discourse.julialang.org/u/uje)\
**Post date:** [September 16, 2022, 3:48pm UTC](https://discourse.julialang.org/t/how-to-overload-operators-and-their-doc-bindings/87372/12 "2022-09-16T15:48:54Z")

</div>

This is not good, but sure it works for now.

But why does the `help` section works this way?

---

<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:** [September 16, 2022, 3:57pm UTC](https://discourse.julialang.org/t/how-to-overload-operators-and-their-doc-bindings/87372/13 "2022-09-16T15:57:02Z")

</div>

> [@uje](#):
>
> But why does the `help` section works this way?

It’s not the help section, it’s the Julia parser in general. You’ll find that `Main.<` _never_ works in Julia.

The basic reason is that `.<` is _also_ a binary operator in Julia. So, `Main.<` is parsed as the beginning of a comparison `Main .< x` … the parser then starts looking for the next expression `x`.

Because of this, Julia provides a way around the ambiguity: you can specify a symbol in a module — or indeed _any_ property of any data structure — as `object.:property` or `object.:(property)`. e.g.

```julia
julia> Main.:<
< (generic function with 74 methods)

julia> z = 3+4im
3 + 4im

julia> z.:re
3

```

This is useful in lots of contexts, not just for help. Most commonly it is used if you want to add new methods to a base operator, like:

```julia
Base.:<(x::String, y::Number) = NaN

```

---

<div class="post-metadata">

**Author:** ![uje](https://avatars.discourse-cdn.com/v4/letter/u/5f9b8f/32.png) [@uje](https://discourse.julialang.org/u/uje)\
**Post date:** [September 16, 2022, 4:00pm UTC](https://discourse.julialang.org/t/how-to-overload-operators-and-their-doc-bindings/87372/14 "2022-09-16T16:00:18Z")

</div>

Thank you.

But I still count it a limitation that the `help` section works that way.

Package developers will then have to do `mypackage.:operator`, just so they can see how a specific operator they defined is used - that’s verbose.

Why not just do `mypackage.operator` or even possible, set this as a flag, so it can be enabled and disabled🙃

---

<div class="post-metadata">

**Author:** ![uje](https://avatars.discourse-cdn.com/v4/letter/u/5f9b8f/32.png) [@uje](https://discourse.julialang.org/u/uje)\
**Post date:** [September 16, 2022, 4:02pm UTC](https://discourse.julialang.org/t/how-to-overload-operators-and-their-doc-bindings/87372/15 "2022-09-16T16:02:48Z")

</div>

A bracket should have been used or allowed to use:

so `Main.:operator` can be `Main.(operator)`; at least this makes sense and the syntax will still be clean  
for cases where `:` will be part of the operator

---

<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:** [September 16, 2022, 4:03pm UTC](https://discourse.julialang.org/t/how-to-overload-operators-and-their-doc-bindings/87372/16 "2022-09-16T16:03:19Z")

</div>

> [@uje](#):
>
> But I still count it a limitation that the `help` section works that way.

The help section is for Julia, so it should use Julia syntax. What other syntax could it use?

---

<div class="post-metadata">

**Author:** ![uje](https://avatars.discourse-cdn.com/v4/letter/u/5f9b8f/32.png) [@uje](https://discourse.julialang.org/u/uje)\
**Post date:** [September 16, 2022, 4:04pm UTC](https://discourse.julialang.org/t/how-to-overload-operators-and-their-doc-bindings/87372/17 "2022-09-16T16:04:09Z")

</div>

`Main.(::)` is very concise and sensible than `Main.:(::)`

---

<div class="post-metadata">

**Author:** ![uje](https://avatars.discourse-cdn.com/v4/letter/u/5f9b8f/32.png) [@uje](https://discourse.julialang.org/u/uje)\
**Post date:** [September 16, 2022, 4:04pm UTC](https://discourse.julialang.org/t/how-to-overload-operators-and-their-doc-bindings/87372/18 "2022-09-16T16:04:49Z")

</div>

I don’t see where `Main.(::)` clashes with anything in the `help` section of the REPL for now. Or does it?

---

<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:** [September 16, 2022, 4:15pm UTC](https://discourse.julialang.org/t/how-to-overload-operators-and-their-doc-bindings/87372/19 "2022-09-16T16:15:50Z")

</div>

No, because `Main.(x)` denotes a “dot call”, equivalent to `broadcast(Main, x)`.

It’s certainly true that there are many different syntactic styles Julia _could_ have chosen. We could have chosen to be more like Python, or more like Rust, or more like Lisp. But the fact of the matter is we _have_ chosen a syntax, and it’s all inter-related — you can’t just change one aspect without changing everything else. Nor is Julia at the stage of development where we are changing basic syntactic structures (see [PSA: Julia is not at that stage of development anymore](https://discourse.julialang.org/t/psa-julia-is-not-at-that-stage-of-development-anymore/44872)), and any new syntax must be added in a carefully nonbreaking way and to solve a real problem, not just because we want a slightly different spelling.

(You may think `Main.:foo` is not “sensible”, but in fact this is very consistent with Julia’s metaprogramming facilities, which require a way of “quoting” symbols.)

---

<div class="post-metadata">

**Author:** ![uje](https://avatars.discourse-cdn.com/v4/letter/u/5f9b8f/32.png) [@uje](https://discourse.julialang.org/u/uje)\
**Post date:** [September 16, 2022, 4:22pm UTC](https://discourse.julialang.org/t/how-to-overload-operators-and-their-doc-bindings/87372/20 "2022-09-16T16:22:52Z")

</div>

`Main.:foo` is sensible but the fact that `Main.:(:)` and also the REPL won’t allow `Foo.>` on the `help` section isn’t great.

```julia
help?> .>
search:

  x .> y is akin to broadcast(>, x, y). See broadcast.

```

The above is great, but it should allow `Foo.>` since `Foo` here is a package or whatever.

- `Foo.>` can’t be a broadcast operation as you’ve said. Its a binary operator and it requires a second argument.

- `Foo.>` can’t be a broadcast operation as you’ve said. Because operators are not allowed in **POSTFIX NOTATION**.

- Operators that are POSTFIX isn’t broadcasted as `arg.'` but rather as `'.arg` or `arg1 .' arg2`.

My point is its isn’t the best style that the `help` section considers `Foo.>` a broadcasting operation as you’ve outlined. It just can’t be.

---

<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:** [September 16, 2022, 4:40pm UTC](https://discourse.julialang.org/t/how-to-overload-operators-and-their-doc-bindings/87372/21 "2022-09-16T16:40:10Z")

</div>

> [@uje](#):
>
> `Foo.>` can’t be a broadcast operation as you’ve said. Its a binary operator and it requires a second argument.

Hence it’s parsed as an incomplete expression:

```julia
julia> Meta.parse("Foo.>")
:($(Expr(:incomplete, "incomplete: premature end of input")))

```

To have a sensible language, whether something counts a complete expression, a single syntactic “unit”, shouldn’t generally depend on what comes _after_ it. We don’t want to parse `x .> y` as a binary operation but then parse `x .>` as something completely different.

Of course, you are free to implement your own language with your own syntax and whatever context-dependent grammar strikes your fancy, maybe even as a front-end for Julia if you want.

[Next page](https://discourse.julialang.org/t/how-to-overload-operators-and-their-doc-bindings/87372.md?page=2)
