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

More explicit representation of undef-ability of fields #25519

Open
Keno opened this issue Jan 11, 2018 · 6 comments
Open

More explicit representation of undef-ability of fields #25519

Keno opened this issue Jan 11, 2018 · 6 comments

Comments

@Keno
Copy link
Member

Keno commented Jan 11, 2018

I was griping to @JeffBezanson that the ability of non-isbits fields to be undef (i.e. throw an UndefRefError) didn't seem very first-class, especially since the definition of what isbits is changing these days. I was suggesting that we might want to have an explicit way to annotate that a field may be undef until defined, independent of whether that field is isbits or not. Possible syntax (names as always subject to bikeshed):

mutable struct foo{T}
    x::Union{Undef, T}
    foo{T}() = new()
end
# With String
@test_throws UndefRefError foo{String}().x # as before
# With Int
@test_throws UndefRefError foo{Int}().x # Instead of returning un-initialized memory as it does now
@vtjnash
Copy link
Member

vtjnash commented Jan 12, 2018

Rust has this. They use it instead of Union{} in type-parameters, since it doesn't suffer the same subtyping issues when applied to dispatch with TypeVars. Fortunately, it's also trivial to create and define:

mutable struct Never
    allow::Never
    let unconstructable end
end
convert(::Type{Union{Never, T}}, x) = convert(T, x) # and a few others, c.f. Some/Nothing

what isbits is changing these days

Not intentional. Will be fixed with my latest PR.

@Keno
Copy link
Member Author

Keno commented Jan 12, 2018

Fortunately, it's also trivial to create and define:

Not sure what you're trying to show with that example. The point would be to throw an UndefRefError on field access.

@vtjnash
Copy link
Member

vtjnash commented Jan 12, 2018

Yes, precisely.

julia> mutable struct foo{T}
           x::Union{Never, T}
           foo{T}() where {T} = new{T}()
       end

julia> foo{Int}().x
ERROR: UndefRefError: access to undefined reference

julia> foo{String}().x
ERROR: UndefRefError: access to undefined reference

@StefanKarpinski
Copy link
Member

What about a ? on the field name?

struct Foo
    baz::Vector{Int}
    bar?::Int
end

For this baz would need to be supplied while bar would not. Of course, the other way to do this would be just to replace undef fields with Union{Nothing,Int} fields and defaulting to nothing, i.e.:

struct Foo
    baz::Vector{Int}
    bar::Union{Nothing,Int}=nothing
end

Of course, this isn't going to land in time for 1.0.

@quinnj
Copy link
Member

quinnj commented Jan 12, 2018

I'm more in favor of @StefanKarpinski's 2nd idea of providing a syntax like Int? to mean Union{Int, Nothing} and getting rid of #undef entirely. One less kinda-form-of-nothingness! Plus we have better support for Unions all-around these days.

@nalimilan
Copy link
Member

See also previous issue about using Union{T, Nothing} (at the time it was Union{T, Null}) at #23721.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants