I’m trying to write a function that outputs arrays that are filled according to a certain computation. I want the user to be able to select the type of the array according to an argument.
Consider these two example functions:
function my_fill1(val, array_constructor::Type{AC}=Array) where {AC<:AbstractArray}
T = typeof(val)
result = AC{T, 1}(undef, 10)
result .= val
result
end
function my_fill2(val; array_constructor::Type{AC}=Array) where {AC<:AbstractArray}
T = typeof(val)
result = AC{T, 1}(undef, 10)
result .= val
result
end
In both versions, I’m using the Type{T}
selector to avoid type instabilities. The only difference between them is that, in the first version, array_constructor
is a positional argument, while, in the second, it is a keyword argument. For my use case, the function has many more arguments, so I would really prefer use the version with keyword arguments.
When I test both versions for type stability with the default values for array_constructor
, I get positive results:
@code_warntype my_fill1(1) # type stable
@code_warntype my_fill2(1) # type stable
Nonetheless, when I overwrite the default values, my_fill1
remains stable while my_fill2
becomes unstable:
@code_warntype my_fill1(1, Array) # type stable
@code_warntype my_fill2(1, array_constructor=Array) # type unstable (output type is Any)
What is going on here? Am I doing something wrong? Thanks in advance for any help!