# Union of Nothing and Parametric Types

**URL:** <https://discourse.julialang.org/t/union-of-nothing-and-parametric-types/11986>\
**Category:** General Usage\
**Tags:** question\
**Created:** [June 26, 2018, 11:25pm UTC](https://discourse.julialang.org/t/union-of-nothing-and-parametric-types/11986 "2018-06-26T23:25:18Z")\
**Posts on this page:** 17\
**Page:** 1

<div class="post-metadata">

**Author:** ![jdlara-berkeley](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jdlara-berkeley/32/4096_2.png) [@jdlara-berkeley](https://discourse.julialang.org/u/jdlara-berkeley)\
**Post date:** [June 26, 2018, 11:25pm UTC](https://discourse.julialang.org/t/union-of-nothing-and-parametric-types/11986/1 "2018-06-26T23:25:18Z")

</div>

Hi, I am trying to define a struct that can take an Array of type T or a nothing, as recommended since Nullables has been deprecated.

```nohighlight
using Compat
struct bar{T <: Real, M <: String}
    a::Union{Nothing,Array{T}}
    b::Array{M}
end
foo = bar(nothing, ["a", "b"])

```

But I get this error

```julia
MethodError: no method matching bar(::Void, ::Array{String,1})
Closest candidates are:
  bar(::Union{Array{T<:Real,N} where N, Void}, ::Array{M<:String,N} where N) where {T<:Real, M<:String} at In[37]:2

```

Which seems very contradictory since the error shows the declared union as possible.

---

<div class="post-metadata">

**Author:** ![quinnj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/quinnj/32/11_2.png) [@quinnj](https://discourse.julialang.org/u/quinnj)\
**Post date:** [June 26, 2018, 11:57pm UTC](https://discourse.julialang.org/t/union-of-nothing-and-parametric-types/11986/2 "2018-06-26T23:57:29Z")

</div>

The issue is that the constructor can’t figure out what `T` is supposed to be. All you’re giving the constructor is `nothing` and no `T` can be inferred. You can circumvent this by doing something like you probably had to do before w/ Nullable:

```julia
struct bar{T <: Real, M <: String}
    a::Union{Nothing,Array{T}}
    b::Array{M}
end
bar(::Type{T}, b::Array{M}) where {T <: Real, M <: String) = bar{T, M}(nothing, b)

```

This solves the problem because you’re now explicitly giving `T` as the 1st argument.

---

<div class="post-metadata">

**Author:** ![djsegal](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/djsegal/32/13752_2.png) [@djsegal](https://discourse.julialang.org/u/djsegal)\
**Post date:** [June 27, 2018, 4:00am UTC](https://discourse.julialang.org/t/union-of-nothing-and-parametric-types/11986/3 "2018-06-27T04:00:43Z")

</div>

Just curious, what’s the difference between `Void` and `Nothing`?

I’ve seen people use both to achieve this `Union` behavior with nil values

* * *

**edit:** nvm. prob related to,

[https://github.com/JuliaLang/julia/issues/25082](https://github.com/JuliaLang/julia/issues/25082)

---

<div class="post-metadata">

**Author:** ![ScottPJones](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/scottpjones/32/146_2.png) [@ScottPJones](https://discourse.julialang.org/u/ScottPJones)\
**Post date:** [June 27, 2018, 2:32pm UTC](https://discourse.julialang.org/t/union-of-nothing-and-parametric-types/11986/4 "2018-06-27T14:32:36Z")

</div>

No difference between `Void` and `Nothing`, just renaming so that it makes more sense, giving that `Void()` is `nothing`, and also because `Missing` and `missing` were added.

So now, unlike most languages, we have the programmer’s null (Nothing), the 3VL null (Missing), still have the `NaN` value for invalid floating point data, and a zero-length string (“”) is also separate.

Which is pretty cool, because most languages mess this up.

---

<div class="post-metadata">

**Author:** ![jdlara-berkeley](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jdlara-berkeley/32/4096_2.png) [@jdlara-berkeley](https://discourse.julialang.org/u/jdlara-berkeley)\
**Post date:** [June 27, 2018, 3:17pm UTC](https://discourse.julialang.org/t/union-of-nothing-and-parametric-types/11986/5 "2018-06-27T15:17:56Z")

</div>

Thi syntax seems to have fixed the problem

```julia
using Compat
struct bar{T <: Union{Nothing,Array{R,1}} where R <: Real, M <: String}
    a::T
    b::Array{M}
end
foo = bar(nothing, ["a", "b"])
foo2 = bar([1.0, 2.0], ["a", "b"])

```

The question is which performs better. From the tips mentioned in [Performance Tips](https://docs.julialang.org/en/v0.6.2/manual/performance-tips/) seems that it should be preferable to declare the union in the parametric type.

A second problem arises when I try to create an inner constructor as follows:

```nohighlight
using Compat
struct bar{T <: Union{Nothing,Array{R}} where R <: Real, M <: String}
    a::T
    b::Array{M}
    function bar{T,M}(a,b) where {T <: Union{Nothing,Array{R}} where R <: Real, M <: String}
        if !isa(a, Nothing)
            new(a*3, b)
        else
            new(nothing, b)
        end
    end
end

```

I get the error

```nohighlight
foo = bar(nothing, ["a", "b"])
ERROR: MethodError: no method matching bar(::Void, ::Array{String,1})
foo2 = bar([1.0, 2.0], ["a", "b"])
ERROR: MethodError: no method matching bar(::Array{Float64,1}, ::Array{String,1})

```

It is not clear to me what the right syntax is in this case.

---

<div class="post-metadata">

**Author:** ![jdlara-berkeley](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jdlara-berkeley/32/4096_2.png) [@jdlara-berkeley](https://discourse.julialang.org/u/jdlara-berkeley)\
**Post date:** [June 27, 2018, 3:18pm UTC](https://discourse.julialang.org/t/union-of-nothing-and-parametric-types/11986/6 "2018-06-27T15:18:55Z")

</div>

Thanks, I will test the solution you provided here.

---

<div class="post-metadata">

**Author:** ![ScottPJones](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/scottpjones/32/146_2.png) [@ScottPJones](https://discourse.julialang.org/u/ScottPJones)\
**Post date:** [June 27, 2018, 4:48pm UTC](https://discourse.julialang.org/t/union-of-nothing-and-parametric-types/11986/7 "2018-06-27T16:48:04Z")

</div>

> [@jdlara-berkeley](#):
>
> struct bar{T \<: Union{Nothing,Array{R,1}} where R \<: Real, M \<: String}

How about this?

```julia
struct Bar{T <: Union{Nothing, Vector{<:Real}} where {M <: AbstractString}}

```

(a bit shorter, also allows M to be any type of string 😀)

---

<div class="post-metadata">

**Author:** ![jdlara-berkeley](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jdlara-berkeley/32/4096_2.png) [@jdlara-berkeley](https://discourse.julialang.org/u/jdlara-berkeley)\
**Post date:** [June 27, 2018, 4:55pm UTC](https://discourse.julialang.org/t/union-of-nothing-and-parametric-types/11986/9 "2018-06-27T16:55:43Z")

</div>

Yes, this works but still has the problem with the inner constructor, thanks.

---

<div class="post-metadata">

**Author:** ![ScottPJones](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/scottpjones/32/146_2.png) [@ScottPJones](https://discourse.julialang.org/u/ScottPJones)\
**Post date:** [June 27, 2018, 5:01pm UTC](https://discourse.julialang.org/t/union-of-nothing-and-parametric-types/11986/10 "2018-06-27T17:01:10Z")

</div>

Does it need to be an inner constructor?  
I never use them unless I really need to restrict the way the type is constructed.

---

<div class="post-metadata">

**Author:** ![jdlara-berkeley](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jdlara-berkeley/32/4096_2.png) [@jdlara-berkeley](https://discourse.julialang.org/u/jdlara-berkeley)\
**Post date:** [June 27, 2018, 5:08pm UTC](https://discourse.julialang.org/t/union-of-nothing-and-parametric-types/11986/11 "2018-06-27T17:08:48Z")

</div>

Yes, in my real application I need something that populates fields in the Struct as well as having some fields be nothing, sort of like the example

```nohighlight
using Compat
struct bar{T <: Union{Nothing,Array{<:Real}} where R <: Real, M <: String}
    a::T
    b::Array{M}
    function bar{T,M}(a,b) where {T <: Union{Nothing,Array{R}} where R <: Real, M <: String}
        if !isa(a, Nothing)
            new(a*3, b)
        else
            new(nothing, b)
        end
    end
end

```

---

<div class="post-metadata">

**Author:** ![ScottPJones](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/scottpjones/32/146_2.png) [@ScottPJones](https://discourse.julialang.org/u/ScottPJones)\
**Post date:** [June 27, 2018, 5:28pm UTC](https://discourse.julialang.org/t/union-of-nothing-and-parametric-types/11986/12 "2018-06-27T17:28:20Z")

</div>

I understand that, I use a structure that using Nothing for 3 of the four parameterized types, when they are not needed.  
I just don’t understand why you need to use an inner constructor, instead of one or two outer constructors.

The following works:

```julia
struct Bar{T <: Union{Nothing, Vector{<:Real}}, S <: AbstractString}
    a::T
    b::Vector{S}
end

Bar(::Type{Nothing}, b::Vector{S}) where {S <: AbstractString} =
    Bar{Nothing, S}(nothing, b)
Bar(a::T, b::Vector{S}) where {T <: Vector{<:Real}, S <: AbstractString} =
    Bar{T, S}(a*3, b)

foo = Bar(nothing, ["a", "b"])
println(foo)
foo2 = Bar([1.0, 2.0], ["a", "b"])
println(foo2)

```

---

<div class="post-metadata">

**Author:** ![jdlara-berkeley](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jdlara-berkeley/32/4096_2.png) [@jdlara-berkeley](https://discourse.julialang.org/u/jdlara-berkeley)\
**Post date:** [June 27, 2018, 5:43pm UTC](https://discourse.julialang.org/t/union-of-nothing-and-parametric-types/11986/13 "2018-06-27T17:43:30Z")

</div>

If you have 3 fields in your struct but you want one to be calculated internally, is that considered bad practice?

For example code like this where the struct takes `a` and `b` but `c` is calculated by the inner constructor as a default and the user never inputs `c`.

```nohighlight
using Compat
struct bar{T <: Union{Nothing,Array{<:Real}}, M <: String}
    a::T
    b::Array{M}
    c::Array{Float64}
    function bar{T,M}(a,b) where {T <: Union{Nothing,Array{<:Real}}, M <: String}
        if !isa(a, Nothing)
            new(a, b, a*3)
        else
            new(nothing, b, [1.0])
        end
    end
end

```

A broader question is when should one use inner constructors?

---

<div class="post-metadata">

**Author:** ![ScottPJones](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/scottpjones/32/146_2.png) [@ScottPJones](https://discourse.julialang.org/u/ScottPJones)\
**Post date:** [June 27, 2018, 5:49pm UTC](https://discourse.julialang.org/t/union-of-nothing-and-parametric-types/11986/14 "2018-06-27T17:49:07Z")

</div>

But, why does that need to be an _inner_ constructor?  
The only time from what I understand you should be using an inner constructor, is if you want to disallow people from creating an instance of “Bar” (it’s confusing for me to see “bar”, since the convention is to be mixed case for module and type names), without some validation of the arguments.

Otherwise, it’s a lot easier to just define a set of outer constructors.

---

<div class="post-metadata">

**Author:** ![jdlara-berkeley](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jdlara-berkeley/32/4096_2.png) [@jdlara-berkeley](https://discourse.julialang.org/u/jdlara-berkeley)\
**Post date:** [June 27, 2018, 7:07pm UTC](https://discourse.julialang.org/t/union-of-nothing-and-parametric-types/11986/15 "2018-06-27T19:07:01Z")

</div>

Thanks, yeah probably the best approach is to define the constructors outside and also avoid a headache. Our objective was to guarantee consistency in the fields by precisely not-allowing user definition of some fields of the struct.

PS. Sorry for the bar in lower case, I just made a sloppy quick example.

---

<div class="post-metadata">

**Author:** ![ScottPJones](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/scottpjones/32/146_2.png) [@ScottPJones](https://discourse.julialang.org/u/ScottPJones)\
**Post date:** [June 27, 2018, 7:43pm UTC](https://discourse.julialang.org/t/union-of-nothing-and-parametric-types/11986/16 "2018-06-27T19:43:33Z")

</div>

Question, do you really need to pass `nothing`?  
You could define two constructors, one with one arg, the other with two args.

---

<div class="post-metadata">

**Author:** ![ScottPJones](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/scottpjones/32/146_2.png) [@ScottPJones](https://discourse.julialang.org/u/ScottPJones)\
**Post date:** [June 27, 2018, 8:09pm UTC](https://discourse.julialang.org/t/union-of-nothing-and-parametric-types/11986/17 "2018-06-27T20:09:56Z")

</div>

I just tested again, using inner constructors, all worked fine:

```julia
struct Bar{T <: Union{Nothing, Vector{<:Real}}, S <: AbstractString}
    a::T
    b::Vector{S}
    c::Array{Float64}

    Bar(b::Vector{S}) where {S <: AbstractString} =
        new{Nothing, S}(nothing, b, [1.0])
    Bar(a::T, b::Vector{S}) where {T <: Vector{<:Real}, S <: AbstractString} =
        new{T, S}(a, b, a*3)
end

foo = Bar(["a", "b"])
println(foo)
foo2 = Bar([1.0, 2.0], ["a", "b"])
println(foo2)

```

---

<div class="post-metadata">

**Author:** ![jdlara-berkeley](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jdlara-berkeley/32/4096_2.png) [@jdlara-berkeley](https://discourse.julialang.org/u/jdlara-berkeley)\
**Post date:** [June 27, 2018, 8:40pm UTC](https://discourse.julialang.org/t/union-of-nothing-and-parametric-types/11986/18 "2018-06-27T20:40:24Z")

</div>

Great, I had no idea it was possible to define two inner constructors in the same struct.

Thanks
