<p dir="auto">I've been thinking about this for a while; and I thought I should share the notion.<br>
I'm happy to have it shouted down as a bad idea (particularly if a good explanation is given),<br>
but I figured I should share, incase it is infact a good idea.</p>
<p dir="auto"><a href="http://docs.julialang.org/en/latest/manual/performance-tips/#avoid-containers-with-abstract-type-parameters" rel="nofollow">We all know that having a container type (etc) contain abstract types is slow.</a>,<br>
thus normal habit for this case, is to instead have containers which contain a consistent, but generic subtype of that abstract type -- because any given container is normally consistent.</p>
<p dir="auto"><em>All examples here are from real code</em></p>
<p dir="auto"><strong>EG1</strong></p>
<p dir="auto">instead of writing</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="function predict(c::LinearClassifier, x::Array{AbstractFloat})"><pre class="notranslate"><code class="notranslate">function predict(c::LinearClassifier, x::Array{AbstractFloat})
</code></pre></div>
<p dir="auto">We write:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="function predict{F&lt;:AbstractFloat}(c::LinearClassifier, x::Array{F})"><pre class="notranslate"><code class="notranslate">function predict{F&lt;:AbstractFloat}(c::LinearClassifier, x::Array{F})
</code></pre></div>
<p dir="auto">But that is a little harder to read -- the type of <code class="notranslate">x</code> is now spread into two locations.<br>
Not too bad though.</p>
<p dir="auto"><strong>Eg 2</strong> Now a more complex function.</p>
<p dir="auto">Consider:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="function train_one!(c::LinearClassifier, x::Array{AbstractFloat}, y::Int64, input_gradient::Array{AbstractFloat}, α::AbstractFloat=0.025f0)"><pre class="notranslate"><code class="notranslate">function train_one!(c::LinearClassifier, x::Array{AbstractFloat}, y::Int64, input_gradient::Array{AbstractFloat}, α::AbstractFloat=0.025f0)
</code></pre></div>
<p dir="auto">If  the type of <code class="notranslate">x</code> and the type of <code class="notranslate">input_gradient</code> are destined to be the same then:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="function train_one!{F&lt;:AbstractFloat}(c::LinearClassifier, x::Array{F}, y::Int64, input_gradient::Array{F}, α::AbstractFloat=0.025f0)"><pre class="notranslate"><code class="notranslate">function train_one!{F&lt;:AbstractFloat}(c::LinearClassifier, x::Array{F}, y::Int64, input_gradient::Array{F}, α::AbstractFloat=0.025f0)
</code></pre></div>
<p dir="auto">But it turns out that, in this case, the type of <code class="notranslate">x</code> and the type of <code class="notranslate">input_gradient</code> are <strong>not</strong> necessarily the same. <code class="notranslate">input_gradient</code> comes from the greater training procedure -- which is currently <code class="notranslate">Float32</code> to save on memory. <code class="notranslate">x</code> however could be a <code class="notranslate">Float32</code> or a <code class="notranslate">Float64</code> depending on what the input data (from an external source) is (The function always returns <code class="notranslate">Float32</code>).</p>
<p dir="auto">So what we have is now:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="function train_one!{F1&lt;:AbstractFloat, F2&lt;:AbstractFloat}(c::LinearClassifier, x::Array{F1}, y::Int64, input_gradient::Array{F2}, α::AbstractFloat=0.025f0)"><pre class="notranslate"><code class="notranslate">function train_one!{F1&lt;:AbstractFloat, F2&lt;:AbstractFloat}(c::LinearClassifier, x::Array{F1}, y::Int64, input_gradient::Array{F2}, α::AbstractFloat=0.025f0)
</code></pre></div>
<p dir="auto">That is looking pretty bad, now that I have multiple type parameters.<br>
The type of <code class="notranslate">x</code>, and of <code class="notranslate">input_gradient</code>, now each involve cross-referencing two lists.<br>
It could perhaps be better with better naming:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="function train_one!{Fx&lt;:AbstractFloat, Fgrad&lt;:AbstractFloat}(c::LinearClassifier, x::Array{Fx}, y::Int64, input_gradient::Array{Fgrad}, α::AbstractFloat=0.025f0)"><pre class="notranslate"><code class="notranslate">function train_one!{Fx&lt;:AbstractFloat, Fgrad&lt;:AbstractFloat}(c::LinearClassifier, x::Array{Fx}, y::Int64, input_gradient::Array{Fgrad}, α::AbstractFloat=0.025f0)
</code></pre></div>
<hr>
<p dir="auto">So what can we do about it?</p>
<p dir="auto">The syntax/syntactic sugar I am  proposing is that subtypes parameters be allowed without names in the argument types.<br>
Exact syntax, I am not to sure on.<br>
It could be <code class="notranslate">GenericType{&lt;:AbstractType}</code>, or perhaps <code class="notranslate">GenericType{_&lt;:AbstractFloat}</code>,<br>
or maybe something else. I'll use the first form for sake of examples.</p>
<p dir="auto">So</p>
<p dir="auto"><strong>Eg1'</strong>.<br>
Before:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="function predict{F&lt;:AbstractFloat}(c::LinearClassifier, x::Array{F})"><pre class="notranslate"><code class="notranslate">function predict{F&lt;:AbstractFloat}(c::LinearClassifier, x::Array{F})
</code></pre></div>
<p dir="auto">After:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="function predict(c::LinearClassifier, x::Array{&lt;:AbstractFloat})"><pre class="notranslate"><code class="notranslate">function predict(c::LinearClassifier, x::Array{&lt;:AbstractFloat})
</code></pre></div>
<p dir="auto"><strong>Eg2</strong><br>
Before:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="function train_one!{Fx&lt;:AbstractFloat, Fgrad&lt;:AbstractFloat}(c::LinearClassifier, x::Array{Fx}, y::Int64, input_gradient::Array{Fgrad}, α::AbstractFloat=0.025f0)"><pre class="notranslate"><code class="notranslate">function train_one!{Fx&lt;:AbstractFloat, Fgrad&lt;:AbstractFloat}(c::LinearClassifier, x::Array{Fx}, y::Int64, input_gradient::Array{Fgrad}, α::AbstractFloat=0.025f0)
</code></pre></div>
<p dir="auto">After:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="function train_one!(c::LinearClassifier, x::Array{&lt;:AbstractFloat}, y::Int64, input_gradient::Array{&lt;:AbstractFloat}, α::AbstractFloat=0.025f0)"><pre class="notranslate"><code class="notranslate">function train_one!(c::LinearClassifier, x::Array{&lt;:AbstractFloat}, y::Int64, input_gradient::Array{&lt;:AbstractFloat}, α::AbstractFloat=0.025f0)
</code></pre></div>
<hr>
<p dir="auto">This can't replace named type parameters. As it does not allow you to say that multiple of your parameters have the same generic type.<br>
But it does I think clean up the cases where each type parameter is used only once.</p>
<p dir="auto">I'm not sure if it breaches the "every feature starts at -100 points" test.<br>
But I wanted to present this as an option.</p>
<p dir="auto">PS: Is their Julep writing guidelines somewhere? I'm happy to reformat this and add additional details.</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="$ julia -v
julia version 0.7.0-beta

$ time julia -e 'println(&quot;hello world&quot;)'
hello world
real    0m0.406s"><pre class="notranslate">$ julia -v
julia version 0.7.0-beta

$ <span class="pl-k">time</span> julia -e <span class="pl-s"><span class="pl-pds">'</span>println("hello world")<span class="pl-pds">'</span></span>
hello world
real    0m0.406s</pre></div>
<p dir="auto">Compare with Perl:</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="$ time perl -e 'print(&quot;hello world&quot;)'
hello world
real    0m0.016s"><pre class="notranslate">$ <span class="pl-k">time</span> perl -e <span class="pl-s"><span class="pl-pds">'</span>print("hello world")<span class="pl-pds">'</span></span>
hello world
real    0m0.016s</pre></div>
<p dir="auto">Or Python:</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="$ time python3 -c 'print(&quot;hello world&quot;)'
hello world
real    0m0.047s"><pre class="notranslate">$ <span class="pl-k">time</span> python3 -c <span class="pl-s"><span class="pl-pds">'</span>print("hello world")<span class="pl-pds">'</span></span>
hello world
real    0m0.047s</pre></div>
<p dir="auto">Or PHP:</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="$ time php -r 'echo &quot;hello world&quot;;'
hello world
real    0m0.047s"><pre class="notranslate">$ <span class="pl-k">time</span> php -r <span class="pl-s"><span class="pl-pds">'</span>echo "hello world";<span class="pl-pds">'</span></span>
hello world
real    0m0.047s</pre></div>
<p dir="auto">Or Ruby:</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="$ time ruby -e 'puts &quot;hello world&quot;'
hello world
real    0m0.187s"><pre class="notranslate">$ <span class="pl-k">time</span> ruby -e <span class="pl-s"><span class="pl-pds">'</span>puts "hello world"<span class="pl-pds">'</span></span>
hello world
real    0m0.187s</pre></div>