Well, I’m a bit disappointed that IndexedTables.jl calls promote_op. It didn’t when I started working on it. But there’s a hierarchy of inference-dependence:
- Best: don’t ever call promote_op or return_type.
- Mostly OK: call return_type, but only use it as a performance hint, making sure to give the same result no matter what it returns.
- Bad: program result depends on return_type.
As for promote_typejoin, we’ll have to take it up with Jameson. If I recall, his concern is about the overhead of copying part of the result every time the element type changes. But I doubt we have sufficient data on this. We could also try style (2) above, using return_type to “guess” an element type.
As for the non-composability of needing promote_typejoin methods for new containers, I agree with David only to a certain point. First, how many row types do we really need? You can represent any kind of array or table data with just tuples, so that type is a rather low-level aspect of the implementation. It doesn’t seem so crazy that a new kind of row would need one extra method to fine-tune its type behavior (certainly, I hope, not affecting correctness!). Second, don’t we need these kinds of definitions anyway? Wouldn’t you similarly want to promote MyRow{DataValue{T}}
and MyRow{DataValue{S}}
?
Don’t worry about that — we already compile way too many specializations and it’s on us to do better. And at risk of stating the obvious, all 2^n won’t actually occur; if you have 50 columns we will not literally need 2^50 methods…