-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
julep: Base.summary
and ShowItLikeYouBuildIt
#18909
Comments
Yes I've been torn between using the type and using a minimal constructor syntax. I think the latter is much better for users to read but the type has seemed more idiomatic. I feel this proposal is a good move. (Generally, I prefer output that you can copy-paste and reconstruct the same (or a very similar) object. It would be wonderful (perhaps somewhat magical/impossible) if the |
I like that idea a lot, and frequently something along those lines kinda works, but there are cases where this runs into fundamental conceptual difficulties: julia> using MappedArrays
julia> a = randn(3,3)
3×3 Array{Float64,2}:
0.458636 -1.19035 1.53639
0.526736 -0.424218 1.42559
-0.526185 -0.143567 -0.135398
julia> b = mappedarray(x->x+1, a)
3×3 MappedArrays.ReadonlyMappedArray{Float64,2,Array{Float64,2},##5#6}:
1.45864 -0.190348 2.53639
1.52674 0.575782 2.42559
0.473815 0.856433 0.864602
julia> b.data === a
true Do you print the values that |
I agree, it's an aspiration only and quite probably is impossible. What about:
Probably a little silly to have a non-type in the header though? |
In some cases that may be impractical or unavoidable if we adopt this strategy, see discussion in JuliaImages/Images.jl#542 (comment) |
+1 for making the summary line more readable, whatever solution is chosen. I just wanted to note that long types happen for other array types which are not necessarily transformations of standard arrays. For these cases, printing the name and parameters of the transformation doesn't work. For example, a julia> freqtable(x)
4-element NamedArrays.NamedArray{Int64,1,Array{Int64,1},Tuple{Dict{ASCIIString,Int64}}}
a 100
b 100
c 100
d 100 That's not the end of the world, but the final Anyway, it might need a different solution we could discuss separately, but I thought I would mention it in case we can find a common strategy. |
In the idiom described here, this would print as 4-element freqtable(::Array{Int64,1}) with element type Int64 Not sure whether you like that more or less. Certainly, specializing |
I'm not sure I like it. In the one-argument case I presented above, |
If there isn't a 1-1 mapping, then indeed that abbreviated form should not be defined. I think you can only define this when the calls produce the type deterministically from any inputs that match the specified types. I also agree this may not be a win in every case; in the package (now at https://github.com/JuliaArrays/ShowItLikeYouBuildIt.jl), see the |
This is how Python defines Is this a seperate issue though? |
Added a 1.0 milestone so we decide whether we want this or not. Relevant links:
Note that the important thing for the milestone is the decision; if we decide we want it, since ShowItLikeYouBuildIt already exists it could be moved into Base pretty quickly. So, decide! |
I like the idea of defining |
I agree with the sentiment. OTOH, (1) we don't currently display enough digits with At least for the world of AbstractArrays, I think the current behavior of ShowItLikeYouBuildIt is |
Yes, please. But that is really its own separate issue |
I think we already have at least an informal recommendation that (2-argument) |
The whole eval-able point has gotten a bit conflated here with the original intent of this issue. In julia> view(reshape(view(rand(10), 2:7), 2, 3), :, 1:2)
2×2 SubArray{Float64,2,Base.ReshapedArray{Float64,2,SubArray{Float64,1,Array{Float64,1},Tuple{UnitRange{Int64}},true},Tuple{}},Tuple{Base.Slice{Base.OneTo{Int64}},UnitRange{Int64}},true}:
0.564978 0.434754
0.0895906 0.520575 if you really wanted to print a statement that could julia> a = reshape(mappedarray(sqrt, 1:12), 3, 4)
3×4 Base.ReshapedArray{Float64,2,MappedArrays.ReadonlyMappedArray{Float64,1,UnitRange{Int64},Base.#sqrt},Tuple{}}:
1.0 2.0 2.64575 3.16228
1.41421 2.23607 2.82843 3.31662
1.73205 2.44949 3.0 3.4641 you should display the output values rather than focusing on This proposal is really focused on 2×2 view(reshape(view(::Array{Float64,1}, 2:7), 2, 3), :, 1:2) with element type Float64 for the summary line in the first case, and 3×4 reshape(mappedarray(sqrt, ::UnitRange{Int}), 3, 4)) with element type Float64 for the second. |
It seems like we should probably do this; We should also perhaps have |
What is |
@KristofferC --- any opinion as one of our resident experts in attractive terminal output? |
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 thanMETADATA.jl
. This has overlap with the concerns and goals of #18068, #18228 (CC @KristofferC), but this is focused (for now) on the workings ofBase.summary
(which prints the "tag line" forAbstractArray
s), 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:
reinterpret
to arbitraryAbstractArray
s, and even making changes that are not possible with a bits-based reinterpretation)SubArray
(Base)ReshapedArray
(Base)PermutedDimsArray
(Base, not exported)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: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:
The proposal is that
summary
(which is called to display objects, not types), the tagline for the above would be shown as something likeor even
For the more complex example above, the part corresponding to the type would be
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 ofRGB
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 asUFixed
numbers.permuteddimsview
is just a wrapper forBase.PermutedDimsArrays.PermutedDimsArray
. For the moment, the trailing element type is completely explicit about the element type---it might stay that way or get abbreviated.The text was updated successfully, but these errors were encountered: