# Trying to understand Union{Nothing, Some{T}}

**URL:** <https://discourse.julialang.org/t/trying-to-understand-union-nothing-some-t/124348>\
**Category:** General Usage\
**Created:** [January 1, 2025, 10:54pm UTC](https://discourse.julialang.org/t/trying-to-understand-union-nothing-some-t/124348 "2025-01-01T22:54:00Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![modn4r](https://avatars.discourse-cdn.com/v4/letter/m/f1d935/32.png) [@modn4r](https://discourse.julialang.org/u/modn4r)\
**Post date:** [January 1, 2025, 10:54pm UTC](https://discourse.julialang.org/t/trying-to-understand-union-nothing-some-t/124348/1 "2025-01-01T22:54:00Z")

</div>

Hi, I am trying to understand the usage of the `Some{T}`:

```julia
function test(x::Union{Some{Float64}, Nothing})
    if isnothing(x)
        println("Nothing!")
    else
        println("Something!")
    end
end

test(nothing) # prints "Nothing!"
test(Some(3.4)) # prints "Something!"
test(Some(nothing)) # MethodError: no method matching test(::Some{Nothing})

```

Given the behaviour of the last result (which I guess makes sense), I don’t understand how this is any better/different from just using `Union{Float64, Nothing}`.  
Likely, I’m misunderstanding, or misusing how Some is expected to work.

---

<div class="post-metadata">

**Author:** ![jakobjpeters](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jakobjpeters/32/207797_2.png) [@jakobjpeters](https://discourse.julialang.org/u/jakobjpeters)\
**Post date:** [January 2, 2025, 12:26am UTC](https://discourse.julialang.org/t/trying-to-understand-union-nothing-some-t/124348/2 "2025-01-02T00:26:29Z")

</div>

In this example, there isn’t really a benefit of `Some{Float64}` over `Float64`. However, it is useful in general to distinguish between `Some{Nothing}` (the value `nothing`) and `Nothing` (the absence of a value).

In this example, say you want to `get` a value from a `Dict{Int, Any}`.

```julia-repl
julia> collection = Dict(1 => "one", 2 => :two, 3 => nothing);

```

There are two ways to do this. You could index the collection directly, but you might run into an error. So, you’d have to wrap it in a try-catch block.

```julia-repl
julia> collection[4]
ERROR: KeyError: key 4 not found

```

This is undesirable, so let’s try the other way: passing a default value.

```julia-repl
julia> get(collection, 3, nothing)

```

In this scenario, there’s no way to distinguish between the key-value pair `3 => nothing` and the failure to find the key `3`, and returning `nothing`. You’d need to use either the try-catch block or create an entirely new sentinel value that the `collection` is not allowed to contain. The use of `Union{Some{T}, Nothing}` would have prevented this issue.

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [January 2, 2025, 12:32am UTC](https://discourse.julialang.org/t/trying-to-understand-union-nothing-some-t/124348/3 "2025-01-02T00:32:21Z")

</div>

As another classic example, consider a function that finds the first first element in an array that fulfills some condition, and returns that element. If no such element is found, the function returns `nothing` instead.

Now, what happens when you pass `isnothing` as the predicate, and give an `Vector{Union{Nothing, Float64}}` as input? The function will return `nothing` but that’s a problem - usually this would signal that no element fulfilled the predicate, but in this case, `nothing` _does_ fulfill it. If the function would return the element wrapped in `Some`, the distinction would be clear. You’d receive a `Some(nothing)` instead, and you’d know that the value that you were looking for is exactly `nothing` (and not that there was no value fulfilling the predicate).

Of course, this is just an example. Similar situations can come up with more complicated predicates.

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [January 2, 2025, 5:10am UTC](https://discourse.julialang.org/t/trying-to-understand-union-nothing-some-t/124348/4 "2025-01-02T05:10:54Z")

</div>

> [@modn4r](#):
>
> `test(x::Union{Some{Float64}, Nothing})`

It’s really worth pointing out that `nothing` is almost never intended to be a working input, and this is done by not writing methods at all. Say you want to find an even number, that’s simple:

```julia
julia> findfirst(iseven, [1, nothing, 2])
ERROR: MethodError: no method matching iseven(::Nothing)

```

and when `nothing` does rarely work, it’s in functions designed just to ignore it:

```julia
julia> something(nothing, nothing, 3)
3

```

It’s precisely because `nothing` is used to _mean_ a result did not exist (I never liked the phrasing “absence of a value” because `nothing` is technically a value of a type), and you handle nonexistent results differently (and usually immediately) from meaningful results. If we need to handle the technical value of `nothing` as metadata, then as already suggested, the easy way to isolate it from the “nonexistent result”-`nothing` that functions can generate is to wrap it or everything in `Some`:

```julia
julia> Some.(findfirst.(isodd, [[2], [1], []])) # nothing as metadata
3-element Vector{Some}:
 Some(nothing)
 Some(1)
 Some(nothing)

julia> [i for i in findfirst.(isodd, [[2], [1], []]) if !isnothing(i)] # handle nothing
1-element Vector{Int64}:
 1

```

It’s worth contrasting this with `missing`, which _does_ have methods written to propagate it and has support for direct elements in containers like `skipmissing` and Missings.jl. Missing data exists, so it has a different meaning from nonexistent results. R makes a similar distinction between [`NA` (“not available”) and `NULL`](https://www.r-bloggers.com/2010/04/r-na-vs-null/), and it doesn’t even let the nonexistent `NULL` be stored in base containers. As that blog hints, you might run into inconsistencies or deviations from the standards (yes there’s more than one); for example, `missing`/`NA` might be used for nonexistent results because the propagating and skipping is convenient for processing, usually justified when missing data isn’t technically possible.

---

<div class="post-metadata">

**Author:** ![modn4r](https://avatars.discourse-cdn.com/v4/letter/m/f1d935/32.png) [@modn4r](https://discourse.julialang.org/u/modn4r)\
**Post date:** [January 2, 2025, 10:20am UTC](https://discourse.julialang.org/t/trying-to-understand-union-nothing-some-t/124348/5 "2025-01-02T10:20:01Z")

</div>

Thanks for the responses. I understand the conceptual difference between `Nothing` and `Some{Nothing}` (though I am wondering how `Missing` fits into all of this), but was wondering how this is used in practice.

I’ve seen `Union{Nothing, Some{T}}` specified as a pattern, but it doesn’t seem to work as expected in my example, unless `T` is left unspecified; otherwise it seems that I would need to use `Union{Nothing, Some{Nothing}, Some{Float64}}`, but then why `Some{Float64}` instead of just `Float64`?

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [January 2, 2025, 10:50am UTC](https://discourse.julialang.org/t/trying-to-understand-union-nothing-some-t/124348/6 "2025-01-02T10:50:14Z")

</div>

I imagine `Union{Nothing, Some{T}}` is supposed to be a field or element type, which wraps the `nothing` the same way `Some(nothing)` does. The `Some{T}` part is likely intended to potentially distinguish nonexistence-`nothing`s from metadata-`nothing`s via `Union{Nothing, Some{Nothing}}`. If metadata-`nothing`s are not necessarily relevant, e.g. `T<:Number`, then you’re right that the typical pattern is `Union{Nothing, T}`; I see that in the wild all the time, but I very rarely see `Some` at all. That still allows `T=Some{U}` when you need it, but `U` is not a parameter that can be shared with the other field types.
