Is a more specialized element type of unique() a breaking change?

I’m working on https://github.com/JuliaLang/julia/pull/28737 to educate myself and have now come to a point where I’m wondering if a more specialized return type of the function unique would be a problem.

Current behaviour taken from a unit test:

unique(x for x in Any[1, 1.0])::Vector{Real} == [1]

Would it be okay to have it like this:

unique(x for x in Any[1, 1.0])::Vector{Int64} == [1]
unique(x for x in Any[1, 1.1])::Vector{Real} == [1,1.1]

?

Is that Syntex free?

It’s not a “more specialized return” (changing return value from Real to Int, i.e. narrowing down the possible types to return is more specialized return), it’s just changing the return type. So yes it is breaking, a possibly minor one, but breaking nonetheless.

It’s also unclear though why you want to make a function more type unstable based on input values.

changing return value from Real to Int , i.e. narrowing down the possible types to return is more specialized > return

Thx - I’ve clearly missed that type parameters in arrays are invariant while writing the question. I understand that this is not actually a more specialized return type.

It came up as a byproduct of me trying to use collect() on an self written Iterator that emits only unique values and the fact that uniqueness is based on isequal(1,1.) === true. So the widening on the output doesn’t happen, because the element is never emitted by the iterator. In my mind the results of this algorithm would be practical covariant, although I now understand better if people rely on determining type via unique their code would fail.

I came across the following behaviour, which, if it would be fixed, would count as breaking too:

julia> g = (x for x in Float32[1,1.]);

julia> c = collect(g);

julia> typeof(unique(g))
Array{Float32,1}

julia> typeof(unique(c))
Array{Float32,1}

julia> typeof(unique(identity,g))
Array{Any,1} # odd one out

julia> typeof(unique(identity,c))
Array{Float32,1}