# \`@forward\` on vectors

**URL:** <https://discourse.julialang.org/t/forward-on-vectors/93121>\
**Category:** New to Julia\
**Tags:** question\
**Created:** [January 17, 2023, 11:34pm UTC](https://discourse.julialang.org/t/forward-on-vectors/93121 "2023-01-17T23:34:57Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![smartalecH](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/smartalech/32/32379_2.png) [@smartalecH](https://discourse.julialang.org/u/smartalecH)\
**Post date:** [January 17, 2023, 11:34pm UTC](https://discourse.julialang.org/t/forward-on-vectors/93121/1 "2023-01-17T23:34:57Z")

</div>

I recently learned about the “delegation” design pattern, and that there are numerous ways one could implement this within Julia. For example, the famous `@forward` macro makes it easy to “delegate” a set of methods meant for one struct to another wrapper struct.

Is there a canonical way to do the same for functions that work on a _vector_ of `structs`? For example, suppose I have something like

```julia
struct foo
val::Int
end

```

and I want to extend the `Base.findfirst()` method to a vector of `foo`s by looking at the `val` member.

Thanks!

---

<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:** [January 18, 2023, 4:29am UTC](https://discourse.julialang.org/t/forward-on-vectors/93121/2 "2023-01-18T04:29:54Z")

</div>

> [@smartalecH](#):
>
> and I want to extend the `Base.findfirst()` method to a vector of `foo`s by looking at the `val` member.

You could certainly overload `findfirst` this way, but it seems like a confusing pun on the meaning of `findfirst`? Or you could define a whole bunch of methods like `==` and so forth that you want to work for comparing a `struct foo` to numbers?

Seems a lot clearer to just write things like `findfirst(==(foo(3)), array_of_foos)`, though, unless `struct foo` is supposed to represent a kind of numbrer?

A lot of the motivation for some of these OOP “design patterns” [goes away thanks to multiple dispatch](https://www.youtube.com/watch?v=kc9HwsxE1OY), which allows you to add [new methods to existing types or new types to existing methods](https://en.wikipedia.org/wiki/Expression_problem) more easily than in OOP languages.

---

<div class="post-metadata">

**Author:** ![smartalecH](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/smartalech/32/32379_2.png) [@smartalecH](https://discourse.julialang.org/u/smartalecH)\
**Post date:** [January 18, 2023, 5:47pm UTC](https://discourse.julialang.org/t/forward-on-vectors/93121/3 "2023-01-18T17:47:34Z")

</div>

Thanks, @stevengj, for your reply.

> but it seems like a confusing pun on the meaning of `findfirst` ?

Yes, this was a bad example on my part. Let me try another example (using one your packages) that might better motivate my question. It may be that there’s a simple “multiple dispatch solution” to this as well (if so, great!) but I’m having trouble thinking through it…

Suppose I was building a system matrix with `GeometryPrimitives.jl`. The package exports an abstract `Shape`, along with various shape subtypes, like `Cylinder`, `Cube`, etc. Importantly, it also exports some useful functions, like `KDTree`, and even overloads `findfirst` to operate on a _vector_ of `Shape` types.

Now suppose I wanted to create a “wrapper” type that had all the attributes of existing shapes, but _also_ had a permittivity field (ε) that I could use to populate my system matrix (or maybe I include various other “material parameters”).

This seems like a prime use case for the “delegation design pattern” (from what I’ve read), as I could simply “forward” all of the existing infrastructure to my new wrapper type. I’m wondering if there’s a clean way to do this with the methods that act on _vectors_ of types too.

But perhaps there’s an even simpler, more idiomatic way to accomplish this? Thanks!

---

<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:** [January 18, 2023, 7:58pm UTC](https://discourse.julialang.org/t/forward-on-vectors/93121/4 "2023-01-18T19:58:02Z")

</div>

> [@smartalecH](#):
>
> Suppose I was building a system matrix with `GeometryPrimitives.jl`. The package exports an abstract `Shape`, along with various shape subtypes, like `Cylinder`, `Cube`, etc. Importantly, it also exports some useful functions, like `KDTree`, and even overloads `findfirst` to operate on a _vector_ of `Shape` types.

In that particular case, `Shape` is an abstract type, so one approach would be to simply declare a subtype that adds metadata, but contains another shape and delegates to it for geometric primitives. Then it will work fine with array methods.

In the case of this particular package, I would caution you that we found in hindsight that working with a `Vector{<:Shape}` performs poorly. See this discussion on a related topic: [Allocation and slow down when # of types involved increase (slower than C++ virtual methods) - #2 by jling](https://discourse.julialang.org/t/allocation-and-slow-down-when-of-types-involved-increase-slower-than-c-virtual-methods/87656/2) … I’ve been meaning to re-work it with something like the approach in [GitHub - YingboMa/Unityper.jl](https://github.com/YingboMa/Unityper.jl), emulating C `union` types to avoid the general case of dynamic dispatch.

I would also say that the KDTree implementation in that package might be better off returning an index into an array of shapes, so that you can simply store metadata about each shape in another array. In general, I think that this package needs some re-working and the difficulty of using it with metadata is a symptom of that.

---

<div class="post-metadata">

**Author:** ![smartalecH](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/smartalech/32/32379_2.png) [@smartalecH](https://discourse.julialang.org/u/smartalecH)\
**Post date:** [January 18, 2023, 8:36pm UTC](https://discourse.julialang.org/t/forward-on-vectors/93121/5 "2023-01-18T20:36:50Z")

</div>

> [@stevengj](#):
>
> simply declare a subtype that adds metadata, but contains another shape and delegates to it for geometric primitives

Ah so simple. Thanks!

> I would also say that the KDTree implementation in that package might be better off returning an index into an array of shapes

I agree. I actually have a version that does this. I can submit a PR if interested. (I even submitted an issue about this [here](https://github.com/stevengj/GeometryPrimitives.jl/issues/38)).

> In the case of this particular package, I would caution you that we found in hindsight that working with a `Vector{<:Shape}` performs poorly.

Yup I remember talking about this awhile back. [Here’s](https://github.com/stevengj/GeometryPrimitives.jl/issues/37) another thread with additional details if anyone else is curious.

Thanks, @stevengj!
