Julia: 0-element fill! errors on wrong type

Created on 23 Oct 2019  路  5Comments  路  Source: JuliaLang/julia

Is there a reason, why this has to error? Or could that be changed?

julia> fill!(Int[], missing)
ERROR: MethodError: Cannot `convert` an object of type Missing to an object of type Int64
Closest candidates are:
  convert(::Type{T}, ::T) where T<:Number at number.jl:6
  convert(::Type{T}, ::Number) where T<:Number at number.jl:7
  convert(::Type{T}, ::Ptr) where T<:Integer at pointer.jl:23
  ...
Stacktrace:
 [1] fill!(::Array{Int64,1}, ::Missing) at .\array.jl:307
 [2] top-level scope at REPL[5]:1

Most helpful comment

Seems a bit questionable. One generally wants to avoid errors that happen or don't happen based on runtime things like how large an array is. This would allow one special case (empty array) when the logic would fail for any other array size.

All 5 comments

Seems a bit questionable. One generally wants to avoid errors that happen or don't happen based on runtime things like how large an array is. This would allow one special case (empty array) when the logic would fail for any other array size.

I'm afraid I don't follow here. The error has nothing to do with the size of the array or "0-element fill!". This is failing solely due to the non-convertable type, for any size. Why should this not error? Or is the argument that fill!([], missing) does not throw? 馃槙

I don't think this is a bug. Please note that Julia doesn't automatically promote types with fill!. Note that

fill!(Any[], missing)

works, as does

fill(Any[1, 2, 3], missing)

OP I think you are looking for

fill!(Union{Int, Missing}[], missing)

The point is that fill! converts the given value to the array's element type exactly once. It could also do it at most once, i.e. not at all for an empty destination. Perfectly possible, but I don't know whether desirable.

Seems a bit questionable. One generally wants to avoid errors that happen or don't happen based on runtime things like how large an array is. This would allow one special case (empty array) when the logic would fail for any other array size.

I see your point and I guess it's a sane decision. I just didn't expect it in the first run, as I thought it'd only fail once it tries to convert, but in my mind filling a zero-length array would be a no-op. But as the length is a runtime information this cannot be a no-op in compilation.

I stumbled over this when implementing append! for some tabular type that shall fill up with missing values if the column doesn't exist in the original table.
Then I wanted to implement vcat(a,b) as consecutive append!s of Table(), a, b.
Which errored as the column in a doesn't allow missing values. But I'll special case append! for empty collections then.

Thanks for sharing your thoughts about this situation. I before expected that to be only necessary for performance (type-stableness) but it also has some helpful validation aspects since it reduces special cases. (which was exactly what I was trying to do when implementing non-mutating appending as appending to an empty table beforehand)

Was this page helpful?
0 / 5 - 0 ratings