Skip to content
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

Syntax for show for Arrays with undef elements? #41947

Open
NHDaly opened this issue Aug 20, 2021 · 2 comments
Open

Syntax for show for Arrays with undef elements? #41947

NHDaly opened this issue Aug 20, 2021 · 2 comments
Labels
domain:arrays [a, r, r, a, y, s] domain:display and printing Aesthetics and correctness of printed representations of objects.

Comments

@NHDaly
Copy link
Member

NHDaly commented Aug 20, 2021

@nassarhuda and I were talking about this this morning, and we were wondering:

Currently vectors with undefined elements print in show with those elements printed as #undef. But this of course is not a valid identifier (it looks like a comment).

We've made great strides towards always printing valid julia code for 2-arg Base.show for most types and containers, via efforts like #32408, #32423, and others.

It would be nice to tie up this neatly for Arrays as well!

Here's an example of the currently not working behavior:

julia> v = Vector{String}(undef, 3); v[2] = "hi"; v
3-element Vector{String}:
 #undef
    "hi"
 #undef

julia> @show Dict(1 => v);
Dict(1 => v) = Dict(1 => [#undef, "hi", #undef])

julia> Dict(1 => v) = Dict(1 => [#undef, "hi", #undef])   # oh no you can't copy paste this! sad beans....


ERROR: syntax: incomplete: premature end of input
Stacktrace:
 [1] top-level scope
   @ none:1

We could maybe take the approach of creating a separate value/identifier that could be printed here, which indicates that the [...] expression should leave those elements undefined.

We of course cannot use the existing undef value for that, because someone might already be putting undef into vectors for whatever reasons (i.e. [undef, 1, undef] is already valid syntax).

We could create a new value for this, maybe like var"#undef", and just tell people "Hey this value can't be put in array literals. Sorry! :)".

So I propose something like this:

julia> struct UndefElementPlaceholder end

julia> const var"#undef" = UndefElementPlaceholder()
UndefElementPlaceholder()

julia> Base.show(io::IO, ::UndefElementPlaceholder) = print(io, "var\"#undef\"")

julia> var"#undef"
var"#undef"

And then change the [] constructor to skip var"#undef" elements, so something like changing:

julia/base/array.jl

Lines 416 to 423 in e4a6f1d

function getindex(::Type{Any}, @nospecialize vals...)
a = Vector{Any}(undef, length(vals))
@inbounds for i = 1:length(vals)
a[i] = vals[i]
end
return a
end
getindex(::Type{Any}) = Vector{Any}()

to:

function getindex(::Type{Any}, @nospecialize vals...)
    a = Vector{Any}(undef, length(vals))
    @inbounds for i = 1:length(vals)
        if vals[i] === var"#undef"
            continue
        end
        a[i] = vals[i]
    end
    return a
end
getindex(::Type{Any}) = Vector{Any}()

With this change, the display of vectors could be changed so that if it contained undefined slots, it would display those slots as var"#undef". For example, something like this:

julia> v = Vector{String}(undef, 3); v[2] = "hi"; v
3-element Vector{String}:
 var"#undef"
        "hi"
 var"#undef"

julia> @show Dict(1 => v);
Dict(1 => v) = Dict(1 => [var"#undef", "hi", var"#undef"])

Thoughts? :) Thanks!

@NHDaly NHDaly added domain:arrays [a, r, r, a, y, s] domain:display and printing Aesthetics and correctness of printed representations of objects. labels Aug 20, 2021
@NHDaly NHDaly added the good first issue Indicates a good issue for first-time contributors to Julia label Oct 5, 2021
@NHDaly
Copy link
Member Author

NHDaly commented Oct 5, 2021

I think this is a good idea, and we've gotten a couple 👍s, so i'm tagging it good first issue for someone to try to implement it! :)

@simeonschaub
Copy link
Member

I must admit I am not a big fan of the idea since it gives users the illusion that #undef is actually a value and users will be even more confused than with the current situation. This behavior is especially surprising if users then try to use it in combination with isbits types and find out they just get random garbage instead.

It also breaks a bunch of assumptions about array literals and Base.vect. The core compiler luckily is separated from Base but I am quite worried this will break a lot of assumptions made by essential functions in Base and lead to hard-to-debug bugs if those values ever leak out. The additional complexity of handling this in the type domain is probably also not very favorable to compile times and invalidations.

I will remove the good first issue tag here since I believe these concerns need to be adressed first.

@simeonschaub simeonschaub removed the good first issue Indicates a good issue for first-time contributors to Julia label Oct 6, 2021
@NHDaly NHDaly assigned NHDaly and unassigned NHDaly Jan 2, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
domain:arrays [a, r, r, a, y, s] domain:display and printing Aesthetics and correctness of printed representations of objects.
Projects
None yet
Development

No branches or pull requests

2 participants