<p dir="auto">I think my ideas <a href="https://github.com/JuliaLang/julia/pull/13412#issuecomment-238327962" data-hovercard-type="pull_request" data-hovercard-url="/JuliaLang/julia/pull/13412/hovercard">here</a> are so far out of the mainstream that they deserve to be beaten up in their own thread.</p>
<ol dir="auto">
<li>
<p dir="auto">Parameterize the type "Function" by its input and output parameters. The following type hierarchy would apply:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="Function{In} &lt;: Function == true
Function{In, Out} &lt;: Function{In} == true"><pre class="notranslate"><code class="notranslate">Function{In} &lt;: Function == true
Function{In, Out} &lt;: Function{In} == true
</code></pre></div>
<p dir="auto">In particular we could have this:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="foo(x::Int, y::Int) = convert(Float, x + y)
z = foo
isa(z, Function{Tuple{Int, Int}, Float}) == true"><pre class="notranslate"><code class="notranslate">foo(x::Int, y::Int) = convert(Float, x + y)
z = foo
isa(z, Function{Tuple{Int, Int}, Float}) == true
</code></pre></div>
<p dir="auto">The set theoretic idea being that the type "Function" from T to S is a (abstract, lazy, or computed) list of Tuple{T, Tuple{T, S}} such that (x, (x, y)) is true for every element in the list:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="Function{T, S} &lt;: AbstractList{Tuple{T, Tuple{T, S}}} == true"><pre class="notranslate"><code class="notranslate">Function{T, S} &lt;: AbstractList{Tuple{T, Tuple{T, S}}} == true
</code></pre></div>
<p dir="auto">For functions with multiple methods the in types would be some form of union, hopefully parameterized to represent any inferences and code supplied restrictions:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="typeof(sin) = Function{T&lt;:Union{Number, AbstractArray}, T}"><pre class="notranslate"><code class="notranslate">typeof(sin) = Function{T&lt;:Union{Number, AbstractArray}, T}
</code></pre></div>
</li>
</ol>
<p dir="auto">So that a function that has been heavily overloaded in a manner that makes type inference difficult ends up as</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="  typeof(difficultfunction) = Function{Union{Tuple{...}, Tuple{...}, ...}, Any}"><pre class="notranslate"><code class="notranslate">  typeof(difficultfunction) = Function{Union{Tuple{...}, Tuple{...}, ...}, Any}
</code></pre></div>
<ol dir="auto">
<li>
<p dir="auto">Add the "maps to" symbol "-&gt;" in the type parameter list of functions to differentiate between type parameters applying to the input and type parameters applying to the output:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="bar{T -&gt; S}(x::T)::S = 2 * x
baz{T -&gt; S}(x::T) = (2 * x)::S"><pre class="notranslate"><code class="notranslate">bar{T -&gt; S}(x::T)::S = 2 * x
baz{T -&gt; S}(x::T) = (2 * x)::S
</code></pre></div>
<p dir="auto">Also this should allow for tying the parameters:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="bac{T -&gt; T}(x::T)::Vector{T} = x .* ones(T, x)"><pre class="notranslate"><code class="notranslate">bac{T -&gt; T}(x::T)::Vector{T} = x .* ones(T, x)
</code></pre></div>
</li>
<li>
<p dir="auto">The result for for closures is that the following syntax covers parameterization:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="g{T -&gt; S, R}(y::T)::Function{S, R} = (x::S -&gt; (x + y)::R)
g{T -&gt; S, R}(y::T) = {S -&gt; R}(x::S -&gt; (x + y)::R)"><pre class="notranslate"><code class="notranslate">g{T -&gt; S, R}(y::T)::Function{S, R} = (x::S -&gt; (x + y)::R)
g{T -&gt; S, R}(y::T) = {S -&gt; R}(x::S -&gt; (x + y)::R)
</code></pre></div>
<p dir="auto">And for truly anonymous Lambdas</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="h = {T -&gt; S}(x::T -&gt; (x + 1)::S)"><pre class="notranslate"><code class="notranslate">h = {T -&gt; S}(x::T -&gt; (x + 1)::S)
</code></pre></div>
</li>
<li>
<p dir="auto">Finally I would like to see the syntax "x::{...}" used for exact pattern matching instead of the "::Val{...}" and "Val{...}()" constructs:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="fal(x::{0}) = 1
fal(x::Int) = x * fal(x - sign(x))"><pre class="notranslate"><code class="notranslate">fal(x::{0}) = 1
fal(x::Int) = x * fal(x - sign(x))
</code></pre></div>
<p dir="auto">Because types in some ways identify sets, in the mathematical sense, it might be interesting to allow:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="fun(x::{0, 1, 2, 3}) = 4"><pre class="notranslate"><code class="notranslate">fun(x::{0, 1, 2, 3}) = 4
</code></pre></div>
<p dir="auto">Reflecting the interpretation that the "::" operator represents the idea of "membership in".</p>
</li>
</ol>
<p dir="auto">I've found a bug in sample. Result gives duplicate elements, c, despite replace=false.<br>
Example code:<br>
<code class="notranslate">c = sample(a, b, replace=false, ordered=true)</code></p>
<p dir="auto">Using JuliaPro-Juno-1.3.1.0 and JuliaPro-Juno-1.3.1.1.</p>