# Does anybody use the syntax \`a \<operator\> b = ...\` to define new methods for operators?

**URL:** <https://discourse.julialang.org/t/does-anybody-use-the-syntax-a-operator-b-to-define-new-methods-for-operators/83034>\
**Category:** General Usage\
**Tags:** question, syntax\
**Created:** [June 19, 2022, 11:14pm UTC](https://discourse.julialang.org/t/does-anybody-use-the-syntax-a-operator-b-to-define-new-methods-for-operators/83034 "2022-06-19T23:14:27Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![dylanxyz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dylanxyz/32/36646_2.png) [@dylanxyz](https://discourse.julialang.org/u/dylanxyz)\
**Post date:** [June 19, 2022, 11:14pm UTC](https://discourse.julialang.org/t/does-anybody-use-the-syntax-a-operator-b-to-define-new-methods-for-operators/83034/1 "2022-06-19T23:14:28Z")

</div>

I know that the julia docs mentions that operators are just regular functions that have a special syntax, so the expressions `a <operator> b` and `<operator>(a, b)` are equivalent. What i did not realized, is that we can use the former in a function definition, for example, `a..b = a:b-1`. My initial thought was that this syntax would be invalid, but i was wrong. I was amazed because i think this syntax is very intuitive and more close to how we define operators in math.

```julia
julia> a..b = a:b-1
.. (generic function with 1 method)

julia> 1..4
1:3

julia> import Base: *

julia> x::Symbol * y::Symbol = Symbol("$x" * "$y")
* (generic function with 368 methods)

julia> :foo * :bar
:foobar

```

I searched the docs to find any mention of defining methods for operators using this syntax, but i did not find anything, so my guess is that most users maybe unaware of this and is not commonly used.

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [June 19, 2022, 11:49pm UTC](https://discourse.julialang.org/t/does-anybody-use-the-syntax-a-operator-b-to-define-new-methods-for-operators/83034/2 "2022-06-19T23:49:43Z")

</div>

Personally I hate it and never use it because I prefer functions to be unambiguously written, and `=` looks too much like assignment. I try to use `function () end` as much as possible and use `()->` when it’s just shorter. I would be happier if I could write `fn }` as shorthand of `function end` in the future, an explicit end of a block expression doesn’t bother me and sometimes saves parenthesizing.

This is more a personal quirk, though, this syntax doesn’t seem like a big deal. The only problematic typo I’ve seen is `_` being mistyped as `-`, so `a_b=1` turns into `a-b=1` (ack!). `a..b == a:b-1` could also be mistyped as `a..b = a:b-1`, but I’m sure people generally know not to.

---

<div class="post-metadata">

**Author:** ![dylanxyz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dylanxyz/32/36646_2.png) [@dylanxyz](https://discourse.julialang.org/u/dylanxyz)\
**Post date:** [June 20, 2022, 12:30am UTC](https://discourse.julialang.org/t/does-anybody-use-the-syntax-a-operator-b-to-define-new-methods-for-operators/83034/3 "2022-06-20T00:30:32Z")

</div>

I’m more of a math person, so it makes sense to me that operators can be defined this way, because is very close to how we define them in math. Of course some times this can be bad for code readability, and using an unambiguous code style (like defining functions with only `function () end`) is preferred for big projects.

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [June 20, 2022, 12:39am UTC](https://discourse.julialang.org/t/does-anybody-use-the-syntax-a-operator-b-to-define-new-methods-for-operators/83034/4 "2022-06-20T00:39:36Z")

</div>

I see your point about it looking like math, but that feature is limited to binary operations on variables. For example, the parser can’t figure out `x^y + 3 = blahblah(x, y, z)`. When I first heard about Julia I saw a Ted talk where it was claimed the code can look like math, along with a graphic of an expression with an integral and a gradient. I learned quickly it was just a weirdly named method rather than separate integration and gradient operators, and I swung back towards a “no fancy stuff” style, maybe a bit too much.

---

<div class="post-metadata">

**Author:** ![dylanxyz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dylanxyz/32/36646_2.png) [@dylanxyz](https://discourse.julialang.org/u/dylanxyz)\
**Post date:** [June 20, 2022, 1:21am UTC](https://discourse.julialang.org/t/does-anybody-use-the-syntax-a-operator-b-to-define-new-methods-for-operators/83034/5 "2022-06-20T01:21:56Z")

</div>

To be fair, the expression `x^y + 3 = blahblah(x, y, z)` makes more sense as an equation than a operator definition, because i don’t think would be valid neither in math or julia to define a binary operator where the left-hand expression is not a binary operator expression, like `x^y`. Of course it would be totally valid as an equation.

---

<div class="post-metadata">

**Author:** ![maxkapur](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/maxkapur/32/21208_2.png) [@maxkapur](https://discourse.julialang.org/u/maxkapur)\
**Post date:** [June 20, 2022, 2:56am UTC](https://discourse.julialang.org/t/does-anybody-use-the-syntax-a-operator-b-to-define-new-methods-for-operators/83034/6 "2022-06-20T02:56:20Z")

</div>

What are the rules for what sorts of characters/strings can be used as operators in this sense?

```julia
julia> acb = a * b
ERROR: UndefVarError: a not defined
Stacktrace:
 [1] top-level scope
   @ REPL[1]:1

julia> (a)c(b) = a * b
ERROR: syntax: "c(b)" is not a valid function argument name around REPL[2]:1
Stacktrace:
 [1] top-level scope
   @ REPL[2]:1

julia> a.c.b = a * b
ERROR: UndefVarError: a not defined
Stacktrace:
 [1] top-level scope
   @ REPL[4]:1

```

Edit: a few more experiments:

```julia
julia> a⨥b = a .+ b
⨥ (generic function with 1 method)

julia> a⌣b = a * abs(b)
ERROR: UndefVarError: b not defined
Stacktrace:
 [1] top-level scope
   @ REPL[7]:1

julia> a…b = a:0.1:b
… (generic function with 1 method)

```

Edit2:  
I guess it’s only those that are listed here: [julia/julia-parser.scm at master · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/blob/master/src/julia-parser.scm)  
Note that many of those operators aren’t defined at all in base, but I assume the developers list them here so that if someone does define them, the operator precedence rules will be consistent with mathematical practice.

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [June 20, 2022, 3:08am UTC](https://discourse.julialang.org/t/does-anybody-use-the-syntax-a-operator-b-to-define-new-methods-for-operators/83034/7 "2022-06-20T03:08:35Z")

</div>

I don’t know of a documented list of operators, but they’re rooted in [julia-parser.scm](https://github.com/JuliaLang/julia/blob/master/src/julia-parser.scm), similar operators will be grouped together. The groups do have differences; they may be parsed differently and the precedence rules among the groups are set in stone. You can also [modify these operators to make new ones](https://docs.julialang.org/en/v1/manual/variables/#man-allowed-variable-names). I don’t do this though, it’s so hard to type.

---

<div class="post-metadata">

**Author:** ![dylanxyz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dylanxyz/32/36646_2.png) [@dylanxyz](https://discourse.julialang.org/u/dylanxyz)\
**Post date:** [June 20, 2022, 3:38am UTC](https://discourse.julialang.org/t/does-anybody-use-the-syntax-a-operator-b-to-define-new-methods-for-operators/83034/8 "2022-06-20T03:38:53Z")

</div>

I pretty sure it will only works for expressions that are parsed as a `call` expression, for example:

```julia
julia> Meta.@dump x * y
Expr
  head: Symbol call
  args: Array{Any}((3,))
    1: Symbol *
    2: Symbol x
    3: Symbol y

julia> Meta.@dump x.y
Expr
  head: Symbol .
  args: Array{Any}((2,))
    1: Symbol x
    2: QuoteNode
      value: Symbol y

```

As you can see, it doesn’t work with something like the `.` operator because is specially parsed. One limitation that i thinked of was the use of `where`, but you can still use it with this syntax if you wrap the expression with parenthesis:

```julia
julia> x::T ± y::T where {T <: Number} = (x + y, x - y)
ERROR: UndefVarError: T not defined
Stacktrace:
 [1] top-level scope
   @ REPL[16]:1

julia> (x::T ± y::T) where {T <: Number} = (x + y, x - y)
± (generic function with 1 method)

julia> 2 ± 3
(5, -1)

```

---

<div class="post-metadata">

**Author:** ![melonedo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/melonedo/32/15503_2.png) [@melonedo](https://discourse.julialang.org/u/melonedo)\
**Post date:** [June 20, 2022, 4:09am UTC](https://discourse.julialang.org/t/does-anybody-use-the-syntax-a-operator-b-to-define-new-methods-for-operators/83034/9 "2022-06-20T04:09:28Z")

</div>

I have never used it because I believe `Base.:(*)` better highlights the intent that I am modifying a function from `Base`. With `a * b` I am restricted to importing before defining because `a Base.:(*) b` does not work 🤷‍♂️
