<p dir="auto">As discussed in <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="994167887" data-permission-text="Title is private" data-url="https://github.com/JuliaLang/julia/issues/42222" data-hovercard-type="issue" data-hovercard-url="/JuliaLang/julia/issues/42222/hovercard" href="https://github.com/JuliaLang/julia/issues/42222">#42222</a>, it is often useful to require a vararg to be non-empty.  However, a generalization of that idea is that one often wants to dispatch on vararg where <em>at least one</em> of the vararg entries is a <em>narrower</em> type, in order to avoid type piracy.  (See e.g. <a href="https://github.com/JuliaDiff/ChainRulesCore.jl/pull/473#discussion_r718908483" data-hovercard-type="pull_request" data-hovercard-url="/JuliaDiff/ChainRulesCore.jl/pull/473/hovercard">this example</a> in ChainRulesCore, cc <a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/oxinabox/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/oxinabox">@oxinabox</a>.)</p>
<p dir="auto">For example, suppose that <code class="notranslate">Base</code> defines a function <code class="notranslate">foo(x::Number...) = 1</code>.    Now, in my own package I want to define a more specialized version of <code class="notranslate">foo</code> when <code class="notranslate">x...</code> includes at least one element of <code class="notranslate">MyNumber</code>:</p>
<div class="highlight highlight-source-julia notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="foo(x::Union{Number,MyNumber}...) = 2"><pre class="notranslate"><span class="pl-en">foo</span>(x<span class="pl-k">::</span><span class="pl-c1">Union{Number,MyNumber}</span>...) <span class="pl-k">=</span> <span class="pl-c1">2</span></pre></div>
<p dir="auto">Unfortunately, the second method is type piracy, and overrides the <code class="notranslate">Base</code> method in <em>all</em> cases.</p>
<p dir="auto">If we had a syntax to declare that at least one of the arguments was a <code class="notranslate">MyNumber</code>, and corresponding support in the dispatch system, that would allow us to obtain the desired dispatch behavior.</p>
<p dir="auto">Syntactically, my suggestion would be to define a new variant of <code class="notranslate">Vararg{T,N}</code>, e.g. <code class="notranslate">VarargOne{T1, T, N}</code>, to denote a tuple of <code class="notranslate">N &gt; 0</code> elements of type <code class="notranslate">Union{T,T1}</code>, at least one of which is of type <code class="notranslate">T1</code>.    This would allow e.g.</p>
<div class="highlight highlight-source-julia notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="foo(x::VarargOne{MyNumber,Number,N}) where {N} = 2"><pre class="notranslate"><span class="pl-en">foo</span>(x<span class="pl-k">::</span><span class="pl-c1">VarargOne{MyNumber,Number,N}</span>) <span class="pl-k">where</span> {N} <span class="pl-k">=</span> <span class="pl-c1">2</span></pre></div>
<p dir="auto">Okay, so this is a bit of a weird feature request, but there are some circumstances, for example when writing a CAS, where you want to dispatch on whether some type <code class="notranslate">T</code> occurs <em>anywhere</em> in an args list. Currently, the only real way to do this is with a trait like mechanism, e.g.</p>
<div class="highlight highlight-source-julia notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="struct T end
struct HasT end
struct DoesntHaveT end

has_T(::Tup) where {Tup &lt;: Tuple} = T ∈ Tup.parameters ? HasT() : DoesntHaveT();

f(args...) = f(has_T(args), args...)
f(::HasT, args...) = 1;
f(::DoesntHaveT, args...) = 2;"><pre class="notranslate"><span class="pl-k">struct</span> T <span class="pl-k">end</span>
<span class="pl-k">struct</span> HasT <span class="pl-k">end</span>
<span class="pl-k">struct</span> DoesntHaveT <span class="pl-k">end</span>

<span class="pl-en">has_T</span>(<span class="pl-k">::</span><span class="pl-c1">Tup</span>) <span class="pl-k">where</span> {Tup <span class="pl-k">&lt;:</span> <span class="pl-c1">Tuple</span>} <span class="pl-k">=</span> T <span class="pl-k">∈</span> Tup<span class="pl-k">.</span>parameters <span class="pl-k">?</span> <span class="pl-c1">HasT</span>() <span class="pl-k">:</span> <span class="pl-c1">DoesntHaveT</span>();

<span class="pl-en">f</span>(args<span class="pl-k">...</span>) <span class="pl-k">=</span> <span class="pl-c1">f</span>(<span class="pl-c1">has_T</span>(args), args<span class="pl-k">...</span>)
<span class="pl-en">f</span>(<span class="pl-k">::</span><span class="pl-c1">HasT</span>, args<span class="pl-k">...</span>) <span class="pl-k">=</span> <span class="pl-c1">1</span>;
<span class="pl-en">f</span>(<span class="pl-k">::</span><span class="pl-c1">DoesntHaveT</span>, args<span class="pl-k">...</span>) <span class="pl-k">=</span> <span class="pl-c1">2</span>;</pre></div>
<div class="highlight highlight-source-julia notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="julia&gt; f(1, 2, 3, T(), 4)
1

julia&gt; f(1, 2, 3, 4)
2"><pre class="notranslate">julia<span class="pl-k">&gt;</span> <span class="pl-c1">f</span>(<span class="pl-c1">1</span>, <span class="pl-c1">2</span>, <span class="pl-c1">3</span>, <span class="pl-c1">T</span>(), <span class="pl-c1">4</span>)
<span class="pl-c1">1</span>

julia<span class="pl-k">&gt;</span> <span class="pl-c1">f</span>(<span class="pl-c1">1</span>, <span class="pl-c1">2</span>, <span class="pl-c1">3</span>, <span class="pl-c1">4</span>)
<span class="pl-c1">2</span></pre></div>
<p dir="auto">I think it would be quite useful if there was a built-in dispatch mechanism for this. Perhaps a syntax like</p>
<div class="highlight highlight-source-julia notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="f(args::Tup) where {Tup &lt;: Tuple, T ∈ Tup} = ..."><pre class="notranslate"><span class="pl-en">f</span>(args<span class="pl-k">::</span><span class="pl-c1">Tup</span>) <span class="pl-k">where</span> {Tup <span class="pl-k">&lt;:</span> <span class="pl-c1">Tuple</span>, T <span class="pl-k">∈</span> Tup} <span class="pl-k">=</span> <span class="pl-k">...</span></pre></div>
<p dir="auto">or even</p>
<div class="highlight highlight-source-julia notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="f(args_left..., ::T, args_right...) = ..."><pre class="notranslate"><span class="pl-en">f</span>(args_left<span class="pl-k">...</span>, <span class="pl-k">::</span><span class="pl-c1">T</span>, args_right<span class="pl-k">...</span>) <span class="pl-k">=</span> <span class="pl-k">...</span></pre></div>
<p dir="auto">where <code class="notranslate">args_right</code> is allowed to have instances of <code class="notranslate">T</code> in it?</p>
<p dir="auto">I get that this is probably too complicated and niche a thing to put in the dispatch system, but I figured I should bring it up in case anyone else and thoughts on this and I didn't see an issue for it.</p>