Issue 1:
I've been thinking about this for a while; and I thought I should share the notion.

I'm happy to have it shouted down as a bad idea (particularly if a good explanation is given),

but I figured I should share, incase it is infact a good idea.

We all know that having a container type (etc) contain abstract types is slow.,

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.

All examples here are from real code

EG1

instead of writing

function predict(c::LinearClassifier, x::Array{AbstractFloat})

We write:

function predict{F<:AbstractFloat}(c::LinearClassifier, x::Array{F})

But that is a little harder to read -- the type of x is now spread into two locations.

Not too bad though.

Eg 2 Now a more complex function.

Consider:

function train_one!(c::LinearClassifier, x::Array{AbstractFloat}, y::Int64, input_gradient::Array{AbstractFloat}, α::AbstractFloat=0.025f0)

If the type of x and the type of input_gradient are destined to be the same then:

function train_one!{F<:AbstractFloat}(c::LinearClassifier, x::Array{F}, y::Int64, input_gradient::Array{F}, α::AbstractFloat=0.025f0)

But it turns out that, in this case, the type of x and the type of input_gradient are not necessarily the same. input_gradient comes from the greater training procedure -- which is currently Float32 to save on memory. x however could be a Float32 or a Float64 depending on what the input data (from an external source) is (The function always returns Float32).

So what we have is now:

function train_one!{F1<:AbstractFloat, F2<:AbstractFloat}(c::LinearClassifier, x::Array{F1}, y::Int64, input_gradient::Array{F2}, α::AbstractFloat=0.025f0)

That is looking pretty bad, now that I have multiple type parameters.

The type of x, and of input_gradient, now each involve cross-referencing two lists.

It could perhaps be better with better naming:

function train_one!{Fx<:AbstractFloat, Fgrad<:AbstractFloat}(c::LinearClassifier, x::Array{Fx}, y::Int64, input_gradient::Array{Fgrad}, α::AbstractFloat=0.025f0)

So what can we do about it?

The syntax/syntactic sugar I am proposing is that subtypes parameters be allowed without names in the argument types.

Exact syntax, I am not to sure on.

It could be GenericType{<:AbstractType}, or perhaps GenericType{_<:AbstractFloat},

or maybe something else. I'll use the first form for sake of examples.

So

Eg1'.

Before:

function predict{F<:AbstractFloat}(c::LinearClassifier, x::Array{F})

After:

function predict(c::LinearClassifier, x::Array{<:AbstractFloat})

Eg2

Before:

function train_one!{Fx<:AbstractFloat, Fgrad<:AbstractFloat}(c::LinearClassifier, x::Array{Fx}, y::Int64, input_gradient::Array{Fgrad}, α::AbstractFloat=0.025f0)

After:

function train_one!(c::LinearClassifier, x::Array{<:AbstractFloat}, y::Int64, input_gradient::Array{<:AbstractFloat}, α::AbstractFloat=0.025f0)

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.

But it does I think clean up the cases where each type parameter is used only once.

I'm not sure if it breaches the "every feature starts at -100 points" test.

But I wanted to present this as an option.

PS: Is their Julep writing guidelines somewhere? I'm happy to reformat this and add additional details.

Issue 2:
$ julia -v
julia version 0.7.0-beta

$ time julia -e 'println("hello world")'
hello world
real 0m0.406s

Compare with Perl:

$ time perl -e 'print("hello world")'
hello world
real 0m0.016s

Or Python:

$ time python3 -c 'print("hello world")'
hello world
real 0m0.047s

Or PHP:

$ time php -r 'echo "hello world";'
hello world
real 0m0.047s

Or Ruby:

$ time ruby -e 'puts "hello world"'
hello world
real 0m0.187s