<p dir="auto">A common pattern with collections is the "groupinds" pattern. The pattern consists of collecting the indices of the entries of the collection into subsets with common value. For example:</p>
<div class="highlight highlight-source-julia notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="v = [(1,2), (1,2), (1,3), (7,3)]"><pre class="notranslate">v <span class="pl-k">=</span> [(<span class="pl-c1">1</span>,<span class="pl-c1">2</span>), (<span class="pl-c1">1</span>,<span class="pl-c1">2</span>), (<span class="pl-c1">1</span>,<span class="pl-c1">3</span>), (<span class="pl-c1">7</span>,<span class="pl-c1">3</span>)]</pre></div>
<p dir="auto">could be grouped into:</p>
<div class="highlight highlight-source-julia notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="[[1,2], [3], [4]]"><pre class="notranslate">[[<span class="pl-c1">1</span>,<span class="pl-c1">2</span>], [<span class="pl-c1">3</span>], [<span class="pl-c1">4</span>]]</pre></div>
<p dir="auto">because the two first indices of <code class="notranslate">v</code> have the same value <code class="notranslate">(1,2)</code>.</p>
<p dir="auto">Could we have this pattern implemented in Base? Below is a draft implementation by <a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/jagot/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/jagot">@jagot</a>:</p>
<div class="highlight highlight-source-julia notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="function group_by(v; f=identity, by=identity)
    isempty(v) &amp;&amp; return [[]]
    e = first(v)
    m = Dict{typeof(by(e)),Vector{typeof(f(1=&gt;e))}}()
    for (i,e) in enumerate(v)
        push!(get!(m, by(e), []), f(i=&gt;e))
    end
    values(m)
end"><pre class="notranslate"><span class="pl-k">function</span> <span class="pl-en">group_by</span>(v; f<span class="pl-k">=</span>identity, by<span class="pl-k">=</span>identity)
    <span class="pl-c1">isempty</span>(v) <span class="pl-k">&amp;&amp;</span> <span class="pl-k">return</span> [[]]
    e <span class="pl-k">=</span> <span class="pl-c1">first</span>(v)
    m <span class="pl-k">=</span> <span class="pl-c1">Dict</span><span class="pl-c1">{typeof(by(e)),Vector{typeof(f(1=&gt;e))}}</span>()
    <span class="pl-k">for</span> (i,e) <span class="pl-k">in</span> <span class="pl-c1">enumerate</span>(v)
        <span class="pl-c1">push!</span>(<span class="pl-c1">get!</span>(m, <span class="pl-c1">by</span>(e), []), <span class="pl-c1">f</span>(i<span class="pl-k">=&gt;</span>e))
    <span class="pl-k">end</span>
    <span class="pl-c1">values</span>(m)
<span class="pl-k">end</span></pre></div>
<p dir="auto">When applying a restriction to a abstract type parameter a subtype it is possible to define a subtype that is not actually a subtype:</p>
<div class="highlight highlight-source-julia notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="julia&gt; abstract type AbstractFoo{T&lt;:Integer} end

julia&gt; struct Foo1{T} &lt;: AbstractFoo{T} end

julia&gt; struct Foo2{T &lt;: Integer} &lt;: AbstractFoo{T} end

julia&gt; Foo1 &lt;: AbstractFoo
false

julia&gt; Foo2 &lt;: AbstractFoo
true"><pre class="notranslate">julia<span class="pl-k">&gt;</span> <span class="pl-k">abstract type</span> AbstractFoo{T<span class="pl-k">&lt;:</span><span class="pl-c1">Integer</span>} <span class="pl-k">end</span>

julia<span class="pl-k">&gt;</span> <span class="pl-k">struct</span> Foo1{T} <span class="pl-k">&lt;:</span> <span class="pl-c1">AbstractFoo{T}</span> <span class="pl-k">end</span>

julia<span class="pl-k">&gt;</span> <span class="pl-k">struct</span> Foo2{T <span class="pl-k">&lt;:</span> <span class="pl-c1">Integer</span>} <span class="pl-k">&lt;:</span> <span class="pl-c1">AbstractFoo{T}</span> <span class="pl-k">end</span>

julia<span class="pl-k">&gt;</span> Foo1 <span class="pl-k">&lt;:</span> <span class="pl-c1">AbstractFoo</span>
<span class="pl-c1">false</span>

julia<span class="pl-k">&gt;</span> Foo2 <span class="pl-k">&lt;:</span> <span class="pl-c1">AbstractFoo</span>
<span class="pl-c1">true</span></pre></div>
<p dir="auto">I believe this to be a bug as by definition <code class="notranslate">Foo1</code> is a subtype of <code class="notranslate">AbstractFoo</code>. Similarly definitions where the subtype attempts to expand the scope of the parameter should probably be disallowed:</p>
<div class="highlight highlight-source-julia notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="struct Foo3{T &lt;: Real} &lt;: AbstractFoo{T} end"><pre class="notranslate"><span class="pl-k">struct</span> Foo3{T <span class="pl-k">&lt;:</span> <span class="pl-c1">Real</span>} <span class="pl-k">&lt;:</span> <span class="pl-c1">AbstractFoo{T}</span> <span class="pl-k">end</span></pre></div>