# Function forwarding for clashing function names

**URL:** <https://discourse.julialang.org/t/function-forwarding-for-clashing-function-names/95318>\
**Category:** General Usage\
**Created:** [February 28, 2023, 9:49am UTC](https://discourse.julialang.org/t/function-forwarding-for-clashing-function-names/95318 "2023-02-28T09:49:40Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![PaterPen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/paterpen/32/27985_2.png) [@PaterPen](https://discourse.julialang.org/u/PaterPen)\
**Post date:** [February 28, 2023, 9:49am UTC](https://discourse.julialang.org/t/function-forwarding-for-clashing-function-names/95318/1 "2023-02-28T09:49:40Z")

</div>

I have general question regarding composition and function forwarding. Let’s assume we have a `struct` car which is composed of a motor and a horn:

```julia
struct car
    m::Motor
    h::Horn
end

```

Both of it’s components implement a function `change!` which allows us to modify internals:

```julia
change!(m::Motor; num_pistons=4) = println("change number of pistons") # dummy function
change!(h::Horn; decibel=90) = println("change volume of tooting") # dummy function

```

Now my natural intention is to try to forward this behaviour to the car itself. For example, the call  
`change!(x::car, num_pistons=6, decibel=100)` should result in `change!(x.motor, num_pistons=6)` and `change!(x.horn, decibel=100)`. However, additionally I want to have the following behaviour:

- keyword arguments are optional, so that we can choose to modify only a subset of (car) components
- if two components have the same keyword argument implemented, use it in both `change!` functions
- if one keyword argument can not be resolved, give an error
- low runtime costs

Is there an elegant way of achieving this? Is this design itself questionable and should be done differently (maybe by instead implementing `change_motor!` and `change_horn!` for a car)?

---

<div class="post-metadata">

**Author:** ![mikmoore](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mikmoore/32/31109_2.png) [@mikmoore](https://discourse.julialang.org/u/mikmoore)\
**Post date:** [February 28, 2023, 3:58pm UTC](https://discourse.julialang.org/t/function-forwarding-for-clashing-function-names/95318/2 "2023-02-28T15:58:46Z")

</div>

One option:

```julia
function change!(c::car; kwargs...)
  motorkws = (:num_pistons,)
  hornkws = (:decibels,)
  kwkeys = keys(kwargs)
  unused = setdiff(kwkeys,motorkws,hornkws)
  isempty(unused) || error("will not use keywords ",unused)
  kw = intersect(kwkeys,motorkws)
  isempty(kw) || change!(c.m;kwargs[kw]...)
  kw = intersect(kwkeys,hornkws)
  isempty(kw) || change!(c.h;kwargs[kw]...)
  return c # or return nothing, etc
end

```

```julia-repl
julia> struct Motor end; struct Horn end; struct car; m::Motor; h::Horn; end

julia> c = car(Motor(),Horn())
car(Motor(), Horn())

julia> change!(c; num_pistons=99)
change number of pistons
car(Motor(), Horn())

julia> change!(c; num_pistons=99, magic=false)
ERROR: will not use keywords [:magic]

```

But the `intersect` and `setdiff` operations here, as well as the `kwargs[kw]` calls resulting from them, will allocate so leave some performance on the table. One could get much more involved with that handling to do better (and perhaps there’s already a package to help), but you’ll have to decide whether that’s worth the programming effort.

Modest performance issues aside, I find this tedious to program. Also, I worry whether it’s such a good idea to have shared keywords distributed everywhere. If you make a `cost` keyword, for example, should that really be applied to every component in the car?

* * *

I think that your `change_motor!` idea is more clear and won’t require all the programming work that will be needed for a single `change!(::car,...)` mega-method. It’s a simple matter of method forwarding

```julia
change_motor!(c::car; kwargs...) = change_motor!(c.m; kwargs...)

```

* * *

When _do_ I use variations on your original pattern here (which isn’t often), they tend to look like this lazy option that gives up some behavioral niceties:

```julia
change!(m::Motor; num_pistons=4, _...) = println("change number of pistons")
change!(h::Horn; decibel=90, _...) = println("change volume of tooting")

function change!(c::car; kwargs...)
  change!(c.m;kwargs...)
  change!(c.h;kwargs...)
  return c
end

```

This will call every function regardless of whether any relevant keywords are present. It will quietly ignore any extra or mis-spelled keywords.

---

<div class="post-metadata">

**Author:** ![PaterPen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/paterpen/32/27985_2.png) [@PaterPen](https://discourse.julialang.org/u/PaterPen)\
**Post date:** [March 2, 2023, 8:59pm UTC](https://discourse.julialang.org/t/function-forwarding-for-clashing-function-names/95318/3 "2023-03-02T20:59:02Z")

</div>

Thanks a lot! Since my application is built for the end-user and should give errors, I can’t really use your lazy option. What do you think about:

```julia
function change!(x::car, field::Symbol; kwargs...)
    y = getfield(x, field)
    change!(y; kwargs...)
end

```

---

<div class="post-metadata">

**Author:** ![mikmoore](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mikmoore/32/31109_2.png) [@mikmoore](https://discourse.julialang.org/u/mikmoore)\
**Post date:** [March 2, 2023, 9:39pm UTC](https://discourse.julialang.org/t/function-forwarding-for-clashing-function-names/95318/4 "2023-03-02T21:39:52Z")

</div>

I would use `getproperty` rather than `getfield`, as properties are considered more user-facing than fields (`getproperty` defaults to `getfield` in any case), but otherwise that’s reasonable.

I’ll remark that having the user call `change!(x, :m; kwargs...)` isn’t really much different from just having them call `change!(x.m; kwargs...)`, nor is it necessarily easier than having them call `change_motor!(x; kwargs...)`. I’d suggest you consider all those options and choose whichever seems “nicest”.

Personally, I use the `change_motor!` pattern most frequently. An advantage is that it’s the easiest one to change (without needing your user to change their code) if you change the representation of `car` later. For example, perhaps you later decide that the “motor” should be contained within a “drivetrain” substructure. The `getfield` approach won’t work (unless you do the transformations on the target field before calling it, at which point it’s basically `getproperty`), `getproperty` can work unchanged if you redefine `getproperty` (which is a little tedious but definitely doable), but for `change_motor!` you can make the tiny change from it using `x.m` to `x.drivetrain.m` and it’s good to go. Or, for even more extensibility, you can change it to call `change_motor!(x.drivetrain; kwargs...)` and add a `change_motor(::Drivetrain; kwargs...)` method to support that.
