-
-
Notifications
You must be signed in to change notification settings - Fork 5.7k
Description
I'm preparing to register a package with the name above, but I realized that this may generate discussion and it seems julia may be a better place for that discussion than METADATA.jl. This has overlap with the concerns and goals of #18068, #18228 (CC @KristofferC), but this is focused (for now) on the workings of Base.summary (which prints the "tag line" for AbstractArrays), so to me this seems better as a separate issue. (I'm also happy to copy/paste this to #18068.)
Background
The good
Between base Julia and its packages, we now have a set of view-types for "changing" what appears to be every aspect of an array:
- changing the apparent element type of an array (or even lazy elementwise computations): MappedArrays (although it's much more than this, it can be thought of as extending
reinterpretto arbitraryAbstractArrays, and even making changes that are not possible with a bits-based reinterpretation) - selecting a subregion of an array:
SubArray(Base) - changing the shape/dimensionality of an array:
ReshapedArray(Base) - changing the order of dimensions of an array:
PermutedDimsArray(Base, not exported) - changing the indices used to address elements of the array: OffsetArrays.
What's more, these are all composable with one another, with little or no performance cost for doing so.
The bad & ugly
Let's suppose someone wants to read a disk file that corresponds to an Array{UInt8,3}, which represents an RGB image with color along the slowest dimension. In the upcoming rewrite of Images---which leverages all this array goodness very heavily---this is a probable type for the resulting "interpreted" array that would display as an RGB image:
julia> typeof(c)
ImageCore.ColorView{ColorTypes.RGB{FixedPointNumbers.UFixed{UInt8,8}},2,MappedArrays.MappedArray{FixedPointNumbers.UFixed{UInt8,8},3,Base.PermutedDimsArrays.PermutedDimsArray{UInt8,3,(3,1,2),(2,3,1),Array{UInt8,3}},ImageCore.##29#30{FixedPointNumbers.UFixed{UInt8,8}},Base.#reinterpret}}This is what appears as part of the output for summary, which is called whenever you display the array in the REPL.
As has been pointed out, that's a mouthful---there's a significant cognitive load spent on just counting brackets.
A proposal
Thinking this over, I noticed that it's often the case that the sequence of characters you type to construct an array is considerably shorter than the sequence of characters in the printed type. Consider this example:
julia> a = rand(3,5,7);
julia> b = view(a, :, 3, 2:5)
3×4 SubArray{Float64,2,Array{Float64,3},Tuple{Colon,Int64,UnitRange{Int64}},false}:
0.616728 0.187771 0.0980549 0.473863
0.540341 0.102319 0.592159 0.779258
0.255608 0.790268 0.776601 0.420463The proposal is that summary (which is called to display objects, not types), the tagline for the above would be shown as something like
3×4 view(::Array{Float64,3}, ::Colon, ::Int, ::UnitRange) with element type Float64or even
3×4 view(::Array{Float64,3}, :, 3, 2:5) with element type Float64For the more complex example above, the part corresponding to the type would be
ColorView{RGB}(ufixedview(N0f8, permuteddimsview(::Array{UInt8,3}, (3,1,2)))) with element type ColorTypes.RGB{FixedPointNumbers.UFixed{UInt8,8}}Without going in to details†, the "radical" thing about this proposal is that we are communicating information about the type from a nested sequence of function calls that would produce such a type.
I am planning to experiment with this in a package at first, but in the long run we may want to contemplate whether show(IOContext(STDERR, compact=true), ::Type{T}) should behave in this way.
†ColorView is both a type and a constructor; the parameter of RGB gets inferred from the eltype of the array you call it on. N0f8 comes from JuliaMath/FixedPointNumbers.jl#51. ufixedview "reinterprets" (via MappedArrays) the entries of an arbitrary (suitable) array as UFixed numbers. permuteddimsview is just a wrapper for Base.PermutedDimsArrays.PermutedDimsArray. For the moment, the trailing element type is completely explicit about the element type---it might stay that way or get abbreviated.