# Method for Base.\* when at least one argument is of a given type

**URL:** <https://discourse.julialang.org/t/method-for-base-when-at-least-one-argument-is-of-a-given-type/103277>\
**Category:** General Usage\
**Tags:** question\
**Created:** [August 28, 2023, 8:49am UTC](https://discourse.julialang.org/t/method-for-base-when-at-least-one-argument-is-of-a-given-type/103277 "2023-08-28T08:49:51Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [August 28, 2023, 8:49am UTC](https://discourse.julialang.org/t/method-for-base-when-at-least-one-argument-is-of-a-given-type/103277/1 "2023-08-28T08:49:51Z")

</div>

Suppose I want to define a vararg method for `Base.*` which is invoked when _at least_ one argument is of a given type `Foo` (for the purposes of this discussion, `struct Foo end` suffices).

What’s the recommended way of doing that? Is there a possibility to do it in a way that composes with other packages that do something similar?

---

<div class="post-metadata">

**Author:** ![oxinabox](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oxinabox/32/206603_2.png) [@oxinabox](https://discourse.julialang.org/u/oxinabox)\
**Post date:** [August 28, 2023, 8:52am UTC](https://discourse.julialang.org/t/method-for-base-when-at-least-one-argument-is-of-a-given-type/103277/2 "2023-08-28T08:52:45Z")

</div>

There is no in-built way.

If you don’t mind defining a ton of methods and can put a reasonable guess on the maximum number of args you need to support, you can use metaprogramming to do so.

I wrote [that pattern up in a blog post](https://www.oxinabox.net/2023/06/17/resident-eval.html#at-least-one-argument-of-this-type).

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [August 28, 2023, 9:01am UTC](https://discourse.julialang.org/t/method-for-base-when-at-least-one-argument-is-of-a-given-type/103277/3 "2023-08-28T09:01:02Z")

</div>

Thanks! That’s what I suspected from looking at the way various packages deal with the question.

IMO the ideal approach would be traits, along the lines of

```julia
# generic code

promote_f_type(::Type{T}, ::Type{S}) where {T,S} = T # the default is: whichever came first
traited_f(::Type, args...) = :the_default
function f(args...)
    T = mapfoldl(typeof, promote_f_type, args)
    traited_f(T, args...)
end

# type-specific extension

struct Foo end
promote_f_type(::Type{Foo}, ::Type) = Foo
promote_f_type(::Type, ::Type{Foo}) = Foo
traited_f(::Type{Foo}, args...) = :Foo_dominates

```

which then make

```julia
julia> f("a", "b") # :the_default
:the_default

julia> f("a", Foo(), "b")
:Foo_dominates

```

but I don’t control `*` or `string`, so this is not viable.

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [August 28, 2023, 9:06am UTC](https://discourse.julialang.org/t/method-for-base-when-at-least-one-argument-is-of-a-given-type/103277/4 "2023-08-28T09:06:47Z")

</div>

If the argument types otherwise differ, won’t that be caught in the promotion machinery? You could try to hook/use that to get a known-to-you wrapper to dispatch on, though it’s not exactly a pretty solution.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [August 28, 2023, 9:13am UTC](https://discourse.julialang.org/t/method-for-base-when-at-least-one-argument-is-of-a-given-type/103277/5 "2023-08-28T09:13:54Z")

</div>

Can you please make this more concrete with an example? I am not sure what promotion machinery you refer to.

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [August 28, 2023, 9:49am UTC](https://discourse.julialang.org/t/method-for-base-when-at-least-one-argument-is-of-a-given-type/103277/6 "2023-08-28T09:49:53Z")

</div>

I was thinking of these:

> <https://github.com/JuliaLang/julia/blob/81978825143e17d2a261e34b88ec7374fb67059c/base/promotion.jl#L422-L425>

But they’re only for `<: Number` and some specific functions, so the approach is not applicable in general.
