# Combinators on Nullables

**URL:** <https://discourse.julialang.org/t/combinators-on-nullables/1481>\
**Category:** Internals & Design\
**Tags:** question\
**Created:** [January 14, 2017, 2:31pm UTC](https://discourse.julialang.org/t/combinators-on-nullables/1481 "2017-01-14T14:31:59Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [January 14, 2017, 2:31pm UTC](https://discourse.julialang.org/t/combinators-on-nullables/1481/1 "2017-01-14T14:31:59Z")

</div>

(This is more of a conceptual question, so I am posting in this category, please reassign if inappropriate. Also, I don’t have a formal CS background, so this may have an obvious answer I missed. Thanks for your understanding.)

Ever since learning about Nullables and reading [Joe Duffy’s blog post about the Midori Error Model](http://joeduffyblog.com/2016/02/07/the-error-model/) which was mentioned in [#7026](https://github.com/JuliaLang/julia/issues/7026), I have been trying to structure my code to handle missing values using these concepts.

Frequently I encounter the following situation: I would like to have some operation which is well-defined on actual values, and I would like to lift it to work on Nullables. To make things concrete, suppose the operation maps a single argument to a single result. There seems to be a standard way of doing this with a combinator, which is called [and\_then in Rust](https://doc.rust-lang.org/std/option/enum.Option.html#method.and_then). My problem with implementing this in Julia is that if the value is null, then I cannot call `f`, so I don’t have a type to use in the Nullable. For example, if I wanted to implement it like

```julia
function and_then{T}(f, x::Nullable{T})
    if isnull(x)
        Nullable{return_type(f, Tuple{T})}() # hypothetical
    else
        Nullable(f(get(x)))
    end
end

```

then I would need to define `return_type`. The following works, most of the time, but it seems like a hack:

```julia
function return_type(f, types)
    rt = Base.return_types(f, types)
    @assert length(rt) == 1 "Could not infer a single return type."
    rt[1]
end

```

Examples:

```julia
julia> f(x) = x+1
f (generic function with 1 method)

julia> and_then(f, Nullable(1))
Nullable{Int64}(2)

julia> and_then(f, Nullable{Int64}())
Nullable{Int64}()

julia> and_then(f, Nullable{String}()) # but f does not work on strings
Nullable{Any}()

```

I could of course provide the return type manually. But this becomes unwieldy when it is rather complex.

Is there a way to implement `and_then` in Julia in some more natural way? Or if not, is this something I should forget about because this is not a good match for the concepts of the language, or are there plans to make it work better?

---

<div class="post-metadata">

**Author:** ![nalimilan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nalimilan/32/147_2.png) [@nalimilan](https://discourse.julialang.org/u/nalimilan)\
**Post date:** [January 14, 2017, 2:40pm UTC](https://discourse.julialang.org/t/combinators-on-nullables/1481/2 "2017-01-14T14:40:02Z")

</div>

The behavior you describe has actually just been implemented as `broadcast` in Julia 0.6 (see [this PR](https://github.com/JuliaLang/julia/pull/16961)). We usually refer to it as “natural lifting semantics”.

So you can now just write `f.(Nullable(1))`.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [January 14, 2017, 2:57pm UTC](https://discourse.julialang.org/t/combinators-on-nullables/1481/3 "2017-01-14T14:57:52Z")

</div>

Thanks — I looked at the PRs, and realized that [this is already documented](http://docs.julialang.org/en/latest/manual/types.html#Performing-operations-on-%5BNullable%5D(@ref)-objects-1).

Now suppose I wanted to implement my own lifting semantics for a type like Rust’s `Result`, which also encodes the error, not merely missingness. What are the standard building blocks from 0.6 that I should use?

---

<div class="post-metadata">

**Author:** ![nalimilan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nalimilan/32/147_2.png) [@nalimilan](https://discourse.julialang.org/u/nalimilan)\
**Post date:** [January 16, 2017, 9:56pm UTC](https://discourse.julialang.org/t/combinators-on-nullables/1481/4 "2017-01-16T21:56:11Z")

</div>

You could just override `broadcast` in a similar way to what this PR did for `Nullable` if you want to support the same syntax. But you could also use a wrapper or meta function, and pass it the function you want as the first argument, like `lift(f, args...)`. This would be more explicit. Depends on your needs.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [January 20, 2017, 3:19pm UTC](https://discourse.julialang.org/t/combinators-on-nullables/1481/5 "2017-01-20T15:19:49Z")

</div>

Consider the following (very stylized) function:

```julia
function calculate(data::Vector)
    T = Int # how to do this non-manually?
    empty = Nullable{Vector{T}}() # return this when failed
    isempty(data) && return empty
    transformed = similar(data, T)
    for (index,elt) in enumerate(data)
        pre_condition(elt) && return empty
        transformed_elt = some_transform(elt)
        post_condition(transformed_elt) && return empty
        transformed[index] = transformed_elt
    end
    Nullable(transformed)
end

```

which transforms some data, but will consider the data invalid when certain things hold (ie empty data, pre- and post-transformation conditions), for which it returns a `Nullable` without a value.

I wonder if there is a way to do this nicer, especially so that I would not have to know the type parameter `T` of the empty `Nullable` but somehow get it automatically. Usually it is more complex than in the example above, and when I modify `some_transform`, it could cease being type-stable, unless I update `empty` accordingly.

Not a problem if this works for `0.6.0` only, I am slowly transitioning anyway.

---

<div class="post-metadata">

**Author:** ![johnmyleswhite](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/johnmyleswhite/32/31_2.png) [@johnmyleswhite](https://discourse.julialang.org/u/johnmyleswhite)\
**Post date:** [January 20, 2017, 3:24pm UTC](https://discourse.julialang.org/t/combinators-on-nullables/1481/6 "2017-01-20T15:24:29Z")

</div>

This problem is why we’ve talking through the compiler changes required to replace the internal representation of `Nullable{T}` with something like `Union{Some{T}, Void}` since you wouldn’t need to know the problematic parameter `T`.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [January 20, 2017, 3:29pm UTC](https://discourse.julialang.org/t/combinators-on-nullables/1481/7 "2017-01-20T15:29:49Z")

</div>

Can you please link to an issue where I could follow this discussion?

---

<div class="post-metadata">

**Author:** ![tkelman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkelman/32/692_2.png) [@tkelman](https://discourse.julialang.org/u/tkelman)\
**Post date:** [January 21, 2017, 9:56pm UTC](https://discourse.julialang.org/t/combinators-on-nullables/1481/8 "2017-01-21T21:56:35Z")

</div>

[https://github.com/JuliaLang/Juleps/pull/21](https://github.com/JuliaLang/Juleps/pull/21)
