-
-
Notifications
You must be signed in to change notification settings - Fork 5.7k
Description
Currently, eltype defaults to Any, for example: eltype(+) === Any. There are a few problems with this fallback:
It is meaningless
Semantically, eltype of X is straightforward. It's the type of the elements which X contain. By having the fallback method in Base, we assert that every possible type contain elements of some kind. That is wrong. If we decided that all types in Julia should be iterable (defaulting to yielding themselves, like the numbers do), then at the very least we should define eltype(x) = typeof(x). However, I think this too is meaningless.
It violates the principle of least surprise
Recently on Slack, a user asked why Julia couldn't infer that eltype(AbstractArray{<:Number}) was Number, but instead returned Any. Mistaking instances for types is a common mistake, but the salient part here is that the mistake would have immeadiately become clear if the eltype call had raised a MethodError. In fact, the element type of a type is not a meaningful concept, but in this case, Julia returned what is essentially a garbage answer instead of correctly complaining that the question was meaningless.
It may lead to silent errors and/or performance traps
For example, if I were to implement a collect-like function taking x as argument, I would return a Vector{eltype(x)}. However, a user using my function on a custom collection type would see the function working without necessarily realizing that they would need to implement eltype for it to be efficient. More reasonable would be for eltype to raise an error.