# Is there a way to automatically define default methods for a type wrapper?

**URL:** https://discourse.julialang.org/t/is-there-a-way-to-automatically-define-default-methods-for-a-type-wrapper/126854
**Category:** General Usage
**Created:** [March 12, 2025, 10:22am UTC](https://discourse.julialang.org/t/is-there-a-way-to-automatically-define-default-methods-for-a-type-wrapper/126854 "2025-03-12T10:22:34Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![TimHargreaves](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/timhargreaves/32/207284_2.png) [@TimHargreaves](https://discourse.julialang.org/u/TimHargreaves)
#### Post date: [March 12, 2025, 10:22am UTC](https://discourse.julialang.org/t/is-there-a-way-to-automatically-define-default-methods-for-a-type-wrapper/126854/1 "2025-03-12T10:22:34Z")

</div>

Suppose a concrete type `Foo` is defined in another package that is unlikely to want any changes made to it. There are many methods defined using `Foo`.

I would like to create a type `Bar` that is essentially the same as `Foo` but has methods for a few new functions I have defined and may have different behaviour for a few existing functions.

My initial thought is to wrap a `Foo`:

```julia
struct Bar
   x::Foo
end

```

I can then define my new functions/custom methods dispatching on `Bar`.

For all other functions, I can create a wrapper that forwards to `Foo`:

```julia
f(x::Bar, y::Real) == f(x.Foo, y)

```

but I’m assuming that there are many methods defined using `Foo` and it would be too much effort to write them all out (or new methods might be added at any point making this hard to maintain).

Is there a way to have this forwarding take place automatically. I.e., if no specific method is defined for `x::Bar` it calls the same method using `x.Foo` instead?

It may instead be helpful to know why this might be a bad idea and to be avoided.

---

<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: [March 12, 2025, 12:12pm UTC](https://discourse.julialang.org/t/is-there-a-way-to-automatically-define-default-methods-for-a-type-wrapper/126854/2 "2025-03-12T12:12:32Z")

</div>

There have been a few macros made for forwarding methods like this, often not even as a focus for the package e.g. `@forward` in MacroTools.jl. Not really sure why people hadn’t arrived at a centralized dependency, but it might be because people prefer to manually forward to it `f(bar.x, y)` when the wrapper doesn’t do any extra processing e.g. `view(x, I)[i] != x[i]`. It doesn’t need to be a strict field structure either, a function can generically get the `Foo` instance `f(getFoo(bar), y)` for a variety of composite types. An unwrapped `Foo` can still be “gotten” by an `identity`-like `getFoo(x::Foo) = x`. Of course, that involves its own busy work, and it’s only appropriate if `Bar` is to be processed to `Foo`. When `Bar` is supposed to behave like `Foo`, then you can’t get around defining methods for the same function, but (1) the aforementioned macros or (2) designing a smaller interface can cut down on the busy work.

---

<div class="post-metadata">

### Author: ![TimHargreaves](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/timhargreaves/32/207284_2.png) [@TimHargreaves](https://discourse.julialang.org/u/TimHargreaves)
#### Post date: [March 12, 2025, 10:08pm UTC](https://discourse.julialang.org/t/is-there-a-way-to-automatically-define-default-methods-for-a-type-wrapper/126854/3 "2025-03-12T22:08:01Z")

</div>

Thank you for the suggestions!

My understanding with these forwarding macros is that you need to specify a list of functions you want forwarding to happen with, which is a bit hard to maintain. I assume there must be a reason, either performance or that it causes bugs why there is no way to do this for all functions as a default.

---

<div class="post-metadata">

### Author: ![simsurace](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/simsurace/32/30216_2.png) [@simsurace](https://discourse.julialang.org/u/simsurace)
#### Post date: [March 12, 2025, 10:46pm UTC](https://discourse.julialang.org/t/is-there-a-way-to-automatically-define-default-methods-for-a-type-wrapper/126854/4 "2025-03-12T22:46:20Z")

</div>

One issue may be that for all functions means also for any future functions and since that would have to be annotated at the struct definition, it can‘t affect any functions defined after that (e.g. in packages depending on that struct). For that, it would have to be supported at the language level forwarding all dispatches.

---

<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: [March 12, 2025, 11:30pm UTC](https://discourse.julialang.org/t/is-there-a-way-to-automatically-define-default-methods-for-a-type-wrapper/126854/5 "2025-03-12T23:30:46Z")

</div>

> [@TimHargreaves](#):
>
> do this for all functions as a default.

That’s impossible when insufficient information is provided. The closest thing to easy forwarding is inheritance (in other languages, Julia doesn’t have classes or concrete subtyping), but you’re still giving critical information to the language about subtyping and structure there. There’s no design where a method `baz(f::Foo)` can flout your manual type restriction to input a completely unrelated `Bar`, let alone know to forward another `baz` call to the nested `Foo`. It’s not hard to run into a problem: if `Bar` contains 2 `Foo` fields, there’s no logical choice for automatic forwarding.

If you want methods to automatically work on both `Foo` and `Bar` in Julia, then they can be annotated with an _abstract_ supertype. It could be as simple as `Union{Foo, Bar}`, or you could make a named supertype `FooLike` in preparation for other `Foo`-like types. The `getFoo` strategy can work for arbitrary substructures (getters are recommended across languages for a reason), but alternatively you could design (and document!) `FooLike` subtypes to share properties rather than contain each other.
