# Passing all functions on object A to object B

**URL:** https://discourse.julialang.org/t/passing-all-functions-on-object-a-to-object-b/134654
**Category:** General Usage
**Tags:** question, type, struct
**Created:** [December 20, 2025, 10:30am UTC](https://discourse.julialang.org/t/passing-all-functions-on-object-a-to-object-b/134654 "2025-12-20T10:30:57Z")
**Posts on this page:** 10
**Page:** 1

<div class="post-metadata">

### Author: ![alequa](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alequa/32/12338_2.png) [@alequa](https://discourse.julialang.org/u/alequa)
#### Post date: [December 20, 2025, 10:30am UTC](https://discourse.julialang.org/t/passing-all-functions-on-object-a-to-object-b/134654/1 "2025-12-20T10:30:58Z")

</div>

Hello,

I have the type:

```julia-auto
struct Car
   color::String
   model::String
   gears::Int
end

```

and I have another struct

```julia-auto
struct CarGroup 
    cars::Vector{Car}
end

```

I would like all the functions called on Car to be applied to CarGroup in this way:

```julia-auto
function color(c::Car)
return c.color
end

function color(cg::CarGroup)
return map(cg.cars) do c
           color(c)
end
end

```

Is this thing even possible with standard language? I imagine that I can define a macro that does and add it to all the functions of interest… but I would much prefer some magic function of the type:

```julia-auto
 function f(cg::CarGroup, args...; kwargs...)
               map(c->f(c, args...;kwargs...), cg,cars)
end
```

---

<div class="post-metadata">

### Author: ![karei](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/karei/32/214809_2.png) [@karei](https://discourse.julialang.org/u/karei)
#### Post date: [December 20, 2025, 11:02am UTC](https://discourse.julialang.org/t/passing-all-functions-on-object-a-to-object-b/134654/2 "2025-12-20T11:02:57Z")

</div>

In most cases, it’s enough to add one forwarding method per function. For example:

```julia
color(cg::CarGroup) = color.(cg.cars)

```

If you’d like to generate these wrappers automatically, you can use a small loop with `@eval`, e.g.:🙂

```julia
for f in (:color, :paint)
    @eval $f(cg::CarGroup, args...; kwargs...) =
        map(c -> $f(c, args...; kwargs...), cg.cars)
end

```

---

<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: [December 20, 2025, 6:55pm UTC](https://discourse.julialang.org/t/passing-all-functions-on-object-a-to-object-b/134654/3 "2025-12-20T18:55:46Z")

</div>

> [@alequa](#):
>
> Is this thing even possible with standard language?

No. The syntax for it does exist, but we’re deliberately prevented from defining one method for arbitrary callables because it silently interferes with other functions’ dispatch e.g. we really don’t want `print(::CarGroup)` calls to be affected:

```julia-auto
julia> function (f::Function)(cg::CarGroup, args...; kwargs...)
           map(c->f(c, args...;kwargs...), cg,cars)
       end
ERROR: cannot add methods to builtin function `Function`
Stacktrace:
 [1] top-level scope
   @ REPL[6]:1

julia> function (f::Any)(cg::CarGroup, args...; kwargs...)
           map(c->f(c, args...;kwargs...), cg,cars)
       end
ERROR: cannot add methods to builtin function `Any`
Stacktrace:
 [1] top-level scope
   @ REPL[7]:1

julia> function (f::F)(cg::CarGroup, args...; kwargs...) where F
           map(c->f(c, args...;kwargs...), cg,cars)
       end
ERROR: function type in method definition is not a type
Stacktrace:
 [1] top-level scope
   @ REPL[5]:1

```

Best we can do is metaprogramming for select callables (see karei’s `@eval` loop), or embrace a higher order function that takes input callables. `map(color, cg.cars)` is already fairly terse, the only possible improvement is a custom higher order function that accesses the `cars` field for us like `carmap(color, cg)`, which doesn’t save much writing.

---

<div class="post-metadata">

### Author: ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)
#### Post date: [December 20, 2025, 8:34pm UTC](https://discourse.julialang.org/t/passing-all-functions-on-object-a-to-object-b/134654/4 "2025-12-20T20:34:35Z")

</div>

Also note that it generally doesn’t really make sense to forward “all” functions in this manner.  
For example, a `recolor(car::Car)::Car` function generalized to `CarGroup` should probably return `CarGroup` back, not a `Vector{Car}` like `map` would do.

---

<div class="post-metadata">

### Author: ![pdeffebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pdeffebach/32/10320_2.png) [@pdeffebach](https://discourse.julialang.org/u/pdeffebach)
#### Post date: [December 22, 2025, 10:27pm UTC](https://discourse.julialang.org/t/passing-all-functions-on-object-a-to-object-b/134654/5 "2025-12-22T22:27:02Z")

</div>

Isn’t the obvious answer to overload broadcast?

---

<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: [December 22, 2025, 11:27pm UTC](https://discourse.julialang.org/t/passing-all-functions-on-object-a-to-object-b/134654/6 "2025-12-22T23:27:46Z")

</div>

Custom broadcasting calls e.g. `color.(x::CarGroup)` are different from sharing direct function calls on scalars and containers `color(x::Union{Car, CarGroup})`. Worth mentioning that broadcasting calls can be shared instead if custom broadcasting is also implemented for `Car` as a 0-dimensional scalar like strings.

---

<div class="post-metadata">

### Author: ![mkitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkitti/32/12459_2.png) [@mkitti](https://discourse.julialang.org/u/mkitti)
#### Post date: [December 23, 2025, 12:54am UTC](https://discourse.julialang.org/t/passing-all-functions-on-object-a-to-object-b/134654/7 "2025-12-23T00:54:24Z")

</div>

# Mapforward macro

You may be able to create a macro that does what you want. I’m out of practice with macro writing, so just regard this as a proof concept. I’m pretty sure I should be escaping symbols.

```julia-repl
julia> struct Car
           color::String
           model::String
           gears::Int
       end

julia> color(c::Car) = c.color
color (generic function with 2 methods)

julia> struct CarGroup
           cars::Vector{Car}
       end

julia> macro mapforward(from::Symbol, to::Symbol)
           quote
               for method in InteractiveUtils.methodswith($from)
                   n = method.name
                   q = quote
                       global $n
                       function $n(cg::CarGroup, args...; kwargs...)
                           map(c->$n(c, args...; kwargs...), cg.cars)
                       end
                   end
                   eval(q)
               end
           end
       end
@mapforward (macro with 1 method)

julia> @mapforward(Car, CarGroup)

julia> cg = CarGroup([
           Car("white","legend", 5),
           Car("red", "integra", 3)
       ])
CarGroup(Car[Car("white", "legend", 5), Car("red", "integra", 3)])

julia> color(cg)
2-element Vector{String}:
 "white"
 "red"

```

# Iteration Interface

Rather than jumping to overload broadcasting, it may be sufficient to implement iteration.

```julia-repl
julia> Base.iterate(cg::CarGroup, args...) = iterate(cg.cars, args...)

julia> Base.length(cg::CarGroup) = length(cg.cars)

julia> color.(cg)
2-element Vector{String}:
 "white"
 "red"

```

---

<div class="post-metadata">

### Author: ![alequa](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alequa/32/12338_2.png) [@alequa](https://discourse.julialang.org/u/alequa)
#### Post date: [December 31, 2025, 2:24pm UTC](https://discourse.julialang.org/t/passing-all-functions-on-object-a-to-object-b/134654/8 "2025-12-31T14:24:11Z")

</div>

Thanks for your clear explanation. I think the @eval loop is quite a clean solution, this way I can clearly define which functions are expected to broadcast within the group and not incur in unexpected behaviours from other functions!

Thanks!

---

<div class="post-metadata">

### Author: ![alequa](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alequa/32/12338_2.png) [@alequa](https://discourse.julialang.org/u/alequa)
#### Post date: [December 31, 2025, 2:28pm UTC](https://discourse.julialang.org/t/passing-all-functions-on-object-a-to-object-b/134654/9 "2025-12-31T14:28:47Z")

</div>

yeah, the map is an example. In the actual use case, I want to dispatch a set of functions to a group without collecting the objects (in-place functions !) ([juliaSNN](https://juliasnn.github.io/SpikingNeuralNetworks.jl/stable/)).

But thanks to stressing it, I ll keep in mind

---

<div class="post-metadata">

### Author: ![alequa](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alequa/32/12338_2.png) [@alequa](https://discourse.julialang.org/u/alequa)
#### Post date: [December 31, 2025, 2:32pm UTC](https://discourse.julialang.org/t/passing-all-functions-on-object-a-to-object-b/134654/10 "2025-12-31T14:32:48Z")

</div>

Thanks a lot for this solution, it works quite well this way!

It’s also nice that I can dispatch the function to the group in different ways depending on the function.

```julia-auto
modifiers = [:paint!, :start!]
properties = [:color, :year]
for f in modifiers
    @eval $f(cg::CarGroup, args...; kwargs...) = begin
        map(c -> $f(c, args...; kwargs...), cg.cars)
        cg 
        end
end

for f in properties
    @eval $f(cg::CarGroup, args...; kwargs...) =
        map(c -> $f(c, args...; kwargs...), cg.cars)
end

```
