I would like to get the array container like v2 without a manual type assertion at the construction. Can this be easily done with some helper function? Thanks!
I don’t know how to do that (probably a proper answer depends on the exact variability of the types you want to support). But, anyway, the most narrow container would be parameterized by the Union of the two types in this case. For performance that probably makes a difference when using the vectors in this specific example.
“The ‘most narrow’ element type” is probably not the most accurate description of my desire. What I want, more specifically, is a consistent type inference across different levels of the composite type myT.
For instance, if I construct an array of the .a fields from v1, I get
This means that as we construct more layers of composite-type instances as containers of parametric-type objects, the type inference capability of the compiler degrades. Consequently, I run into issues maintaining the type stability of methods that operate on multiple levels of highly hierarchical composite types with predefined type parameter bounds. Sometimes, I even encounter MethodError with the input argument as an array, even though the method should have worked if the compiler had not failed to propagate the type inference consistently.
Element type inference isn’t done by the compiler, there’s a separate mechanism for Array literals, and in your case it’s making a broader type than you’d like. You also don’t want the compiler doing element type inference the way it does variable type inference because it would infer the Union of the two types that lmiq mentioned, which you also don’t want. The discrepancy is because the compiler is incentivized to narrow things down as much as possible, while a mutable array is incentivized to permit more types by typejoining or promotion. Manual inference is the way to go here because no automatic inference can satisfy every use case; the type you did get or the narrowest Union could be satisfactory results in other contexts, and the algorithm cannot know which.
Personally, I would still hope for a more consistent type bound across different levels of a composite type. Regardless of how differently the compiler-based type inference and the specific mechanism for array-like objects work, I would think v1_b and v1_c have a consistent type parameter bound since they have a similar IR procedure:
The IR is showing nothing about the runtime element type inference in materialize. It’s not even consistent per input type, it heavily relies on the runtime values:
The method foo, input x’s type, and even x’s values didn’t change, but the runtime value of a concretely typed global variable still made the output’s element type vary across Union{Missing, Int}, Int, or Missing. This usually trips up people starting to process missing data in tables.
It’s not impossible for hypothetical broadcasting to start a deterministic inference at the input arrays’ element types, but again, the standard and only reliable way to do that is manual inference. Automatic inference (and promotion, as you can see in the 1 → 1.0 change) can only guess at what other elements you might want to put in the array for your situation because there’s no one right answer.