Use of _default_eltype



I have seen code in set, collect make use of _default_eltype(typeof(g)) which basically calls Core.Inference....

I don’t know Julia internal very well. My understanding is that Core.Inference is solely for compilation. It feels a bit odd to do type inference in run time. Wouldn’t it be slow?

E.g. collect(g::Generator) would have to invoke run time inference for each g

Do Julia libs normally call Inference in run time if static inferences are insufficient?


It’s a hack so that comprehensions/generators can be mostly type stable while stop people from complaining that they don’t work for empty input. It’s only used in cases where the type cannot be decided from runtime values (empty iterator) and is not computable (which is the case in general).

type inference has special handling to infer the result of this function statically. If this can’t be done then yes, there will be a slow inference call at runtime. It’ll only be used for empty case so it shouldn’t matter that much.

function Set(g::Generator)
    T = _default_eltype(typeof(g))
    (isleaftype(T) || T === Union{}) || return grow_to!(Set{T}(), g)
    return Set{T}(g)

function collect(itr::Generator)
    isz = iteratorsize(itr.iter)
    et = _default_eltype(typeof(itr))
    if isa(isz, SizeUnknown)
        return grow_to!(Array{et,1}(0), itr)
        st = start(itr)
        if done(itr,st)
            return _array_for(et, itr.iter, isz)
        v1, st = next(itr, st)
        collect_to_with_first!(_array_for(typeof(v1), itr.iter, isz), v1, itr, st)

In these examples, _default_eltype is always called regardless of generator being empty or not.


It’s called, but when possible inference will compute it at compile time, so that there’s no runtime overhead for type stable cases. For other cases, maybe the call could be moved below the conditionals so that it’s effectively not called when not used. Maybe the compiler already performs this optimization though – one would have to check.