# Good template for defining a custom type with an addition method

**URL:** https://discourse.julialang.org/t/good-template-for-defining-a-custom-type-with-an-addition-method/101725
**Category:** General Usage
**Tags:** type, methods
**Created:** [July 18, 2023, 11:35am UTC](https://discourse.julialang.org/t/good-template-for-defining-a-custom-type-with-an-addition-method/101725 "2023-07-18T11:35:05Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![pierre-haessig](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pierre-haessig/32/217129_2.png) [@pierre-haessig](https://discourse.julialang.org/u/pierre-haessig)
#### Post date: [July 18, 2023, 11:35am UTC](https://discourse.julialang.org/t/good-template-for-defining-a-custom-type-with-an-addition-method/101725/1 "2023-07-18T11:35:05Z")

</div>

Hello,

I’m implementing for the first time a custom type with a **custom addition method** (i.e. the `+` operator). Unless I missed something in the manual, I didn’t find a paragraph focused on the topic.

After several iterations, I arrived at this result which seems to work (re-expressed for a dummy custom `Point` type)

```julia
module MyModule
    import Base
    export Point, +

    struct Point{T<:Real}
        x::T
        y::T
    end

    function Base.:+(a::Point{<:Real}, b::Point{<:Real})
        return Point(a.x + b.x, a.y + b.y)
    end
end

using .MyModule

a = Point(1.0, 2.0)
b = Point(3.0, 3.0)

print(a+b)

```

My questions are:

1. is it indeed the correct/recommended approach to define a custom type in a module?
2. is there a dedicated section of the manual that I missed?

If indeed there is no dedicated section in the manual, here is a description of what non trivial pieces of information I think I had to gather using the current state of the documentation.

To arrive at the above result, I needed to merge elements from:

- the [Methods](https://docs.julialang.org/en/v1/manual/methods/) chapter, which explains methods and redefinition, but says nothing about _redefining base methods_
- the [Interfaces](https://docs.julialang.org/en/v1/manual/interfaces/) chapter, which focuses a lot on container types (for indexing…) but doesn’t mention the “simple algebraic operations” interface: +,-,\*,/…)
- plus a bit of [Parametric Composite Types](https://docs.julialang.org/en/v1/manual/types/#man-parametric-composite-types) (e.g. for the correct method signature to accept all arguments of type Point{T} where T is a subtype of Real)

also, some background knowledge about modules is needed. In particular, unlike methods of object oriented languages like Python, there is a need to export both the type and each of its methods (unless I missed something).

For comparison, although the concept of special methods is not as strong in Julia, there is a dedicated section in the Python language reference [3 Data model / 3.3. Special method names](https://docs.python.org/3/reference/datamodel.html#special-method-names) which covers addition, comparison, indexing…

To summarize, I think the elements I missed (in the process of finding a solution that works) are:

- the explanation about the need to import `Base` and the need to redefine `Base.:+` (insteadi of just implementing `function +(...)` and also, as a detail, not forgetting the `:` prefix… which is not needed when defining `function +(...)`)
- and then the need to export + (but not Base.+).

---

<div class="post-metadata">

### Author: ![abraemer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/abraemer/32/51403_2.png) [@abraemer](https://discourse.julialang.org/u/abraemer)
#### Post date: [July 18, 2023, 12:35pm UTC](https://discourse.julialang.org/t/good-template-for-defining-a-custom-type-with-an-addition-method/101725/2 "2023-07-18T12:35:15Z")

</div>

I agree that this example is not explained well in the manual. At least I did not find a very clear explanation by searching briefly.

The important thing to realize is that `+` does not universally denote the same function. Function names are no different than variable names - they share the same namespace if you wish. For example you could extend your code with

```julia
let - = +
    println(a-b)
end

```

and it would just work and do the same as your `a+b`.

What does that mean for your example?

1. When you want to add a method to `+` you really mean `+` from `Base`, which needs to be written as `Base.:+` in a function definition (I think this syntax is explained somewhere but I didn’t find it quickly - somewhat confusingly when importing something both `import Base.+` and `import Base.:+` work).
2. To add a method to an existing function from a package you are `using`, you need to use its full name in the definition `function Base.:+(...)` as `function +(...)` would introduce a new _local_ function named `+` and shadow `Base.:+` in the local scope, meaning you could not add things anymore.
3. On the other hand, if you `import` the other module, then `function +(...)` would NOT define a new function and just add a new method to the existing function! This a crucial difference between `using` and `import`, that’s explained in the [FAQ](https://docs.julialang.org/en/v1/manual/faq/#What-is-the-difference-between-%22using%22-and-%22import%22?) but perhaps could use an example for illustration.
4. So generally you need to _either_ `import` modules to add methods to their functions _or_ use the long form of the method’s name (like `Module.function`) in the function definition. I personally would always recommend the latter as that makes it more clear to the reader that an external function is extended (imo).
5. You don’t need to (re)export `+` from `MyModule` as it is identical with `Base.:+`.

So you can simplify your code to:

```julia
module MyModule
    export Point

    struct Point{T<:Real}
        x::T
        y::T
    end

    function Base.:+(a::Point, b::Point) # no need to repeat the type parameter if unused
        return Point(a.x + b.x, a.y + b.y)
    end
end

using .MyModule

a = Point(1.0, 2.0)
b = Point(3.0, 3.0)

print(a+b)

```

---

<div class="post-metadata">

### Author: ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)
#### Post date: [July 18, 2023, 1:06pm UTC](https://discourse.julialang.org/t/good-template-for-defining-a-custom-type-with-an-addition-method/101725/3 "2023-07-18T13:06:17Z")

</div>

> [@pierre-haessig](#):
>
> is it indeed the correct/recommended approach to define a custom type in a module?

That’s only a question of how you want to organize your code.

---

<div class="post-metadata">

### Author: ![pierre-haessig](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pierre-haessig/32/217129_2.png) [@pierre-haessig](https://discourse.julialang.org/u/pierre-haessig)
#### Post date: [July 18, 2023, 3:17pm UTC](https://discourse.julialang.org/t/good-template-for-defining-a-custom-type-with-an-addition-method/101725/4 "2023-07-18T15:17:14Z")

</div>

Thanks a lot for the explanations. In particular the reference to the FAQ [What is the difference between “using” and “import”?](https://docs.julialang.org/en/v1/manual/faq/#What-is-the-difference-between-%22using%22-and-%22import%22?), because I was now wondering how come I had been using the `+` operator all these years without first import/using Base…

_(As a side note, I cannot find the reference which explains how Base is automatically “used” in environment.)_

In the end, I agree with your preference (item 4.) to use the qualified name `Base.:+` for adding a method. This is clearer saves the need to add an extra import statement which, in a complex code base, appears in another file…

---

<div class="post-metadata">

### Author: ![stillyslalom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stillyslalom/32/45687_2.png) [@stillyslalom](https://discourse.julialang.org/u/stillyslalom)
#### Post date: [July 18, 2023, 3:31pm UTC](https://discourse.julialang.org/t/good-template-for-defining-a-custom-type-with-an-addition-method/101725/5 "2023-07-18T15:31:22Z")

</div>

> _(As a side note, I cannot find the reference which explains how Base is automatically “used” in environment.)_

```julia
help?> baremodule
search: baremodule

  baremodule

  baremodule declares a module that does not contain using Base or local 
  definitions of eval and include. It does still import Core. In other words,

  module Mod
  ...
  end

  is equivalent to

  baremodule Mod

  using Base

  eval(x) = Core.eval(Mod, x)
  include(p) = Base.include(Mod, p)
  ...
  end

```

---

<div class="post-metadata">

### Author: ![pierre-haessig](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pierre-haessig/32/217129_2.png) [@pierre-haessig](https://discourse.julialang.org/u/pierre-haessig)
#### Post date: [July 20, 2023, 3:22pm UTC](https://discourse.julialang.org/t/good-template-for-defining-a-custom-type-with-an-addition-method/101725/6 "2023-07-20T15:22:53Z")

</div>

Ah yes `baremodule`, thanks.

The exact reference is indeed in the Manual in [Modules / Namespace management / Default top-level definitions and bare modules](https://docs.julialang.org/en/v1/manual/modules/#Default-top-level-definitions-and-bare-modules):

> Modules automatically contain `using Core`, `using Base`, and definitions of the [`eval`](https://docs.julialang.org/en/v1/base/base/#Base.MainInclude.eval) and [`include`](https://docs.julialang.org/en/v1/base/base/#Base.MainInclude.include) functions, …
