On Friday, 29 May 2015 15:58:12 UTC-3, Yichao Yu wrote:
>
> On Fri, May 29, 2015 at 2:12 PM, andrew cooke <[email protected]
> <javascript:>> wrote:
> > then Julia needs a Maybe type as well?
>
> Note that different from `Nullable{T}`, which is a type by itself,
> `Maybe{T}` as proposed in the issue and you email, is just a type
> alias. In this sense, it is already defined (just write
> `Union(Nothing, ...)`) and it can already appear in type inference.
>
> ```
> julia> f(a) = a > 0 ? nothing : 1
> f (generic function with 1 method)
>
> julia> @code_typed f(1)
> 1-element Array{Any,1}:
> :($(Expr(:lambda, Any[:a],
> Any[Any[],Any[Any[:a,Int64,0]],Any[],Any[]], :(begin # none, line 1:
> unless (top(slt_int))(0,a::Int64)::Bool goto 0
> return nothing
> 0:
> return 1
> end::Union(Int64,Void)))))
> ```
>
> It might make sense to add such a type alias if a lot of people need
> to write it but I personally don't think that's the case.
>
> First of all, if the function returns a certain concrete type or
> nothing, the type inference can figure that out by itself (as shown
> above) and you don't need to tell it anything about that.
>
> Second, you probably don't want to write that as the type constraint
> of the argument either. If the function doesn't have any other
> methods, writing that is meaningless (except as sanity check probably)
> since julia will specialize on the concrete type anyway. If the
> function has other methods, you will introduce ambiguity.
>
> ```julia
> julia> f(::Union(Int, Void)) = 1
> f (generic function with 1 method)
>
> julia> f(::Union(Float64, Void)) = 2
> Warning: New definition
> f(Union(Float64, Void)) at none:1
> is ambiguous with:
> f(Union(Int64, Void)) at none:1.
> To fix, define
> f(Void)
> before the new definition.
> f (generic function with 2 methods)
> ```
>
> For your usecase, according to what you've described, I don't think
> you will need to explicitly writh `Union(Nothing, ...)`
>
> 1. If you want to dispatch on a single Nothing and if the input has
> arbitrary types, just check for nothing explicitly or defining
> `f(::Nothing)`
> 2. If you want to distinguish between different types of Nothing (i.e.
> if the input is a missing Int or a missing Float64), you can probably
> use `Nullable{T}()` as the returned missing value. Whether you want to
> return Nullable or not for non-missing value depends on whether you
> want the user function (that generates the input value) to be type
> stable.
>
1 doesn't work because the user may have "meant to return the value
Nothing". that's why you need a type. because you need to go to a
metalanguage to describe having no value in the lower level language (aka
use / mention ditinction). i don't share your worry with type stability
yet because i have no idea if i can even do what i want - whether it is
fast or not comes much later. but i do want the user to be able to return
"anything" or "decide not to return anything at all", and since "anything"
can be literally Nothing, i cannot use a type union.
so there seems to be a (3) which is unconnected with type stability, but
allows quoting. this is the kind of Maybe that haskell has (and what i was
thinking of when i suggested that Julia needed one). but since it is
structurally equivalent to Nullable then it seems like Nullable would do
just fine there.
> >
> > On Friday, 29 May 2015 10:16:40 UTC-3, andrew cooke wrote:
> >>
> >>
> >> I'm not sure if I'm confused, or if there's a problem here, and I don't
> >> know what any fix would be anyway, so apologies for the open-ended post
> >> but...
> >>
> >> I cannot find on "option" type in Julia that I can dispatch on, so that
> I
> >> have a method call different functions, depending on whether a value is
> >> present or not.
> >>
> >> What I think I need is:
> >>
> >> typealias Maybe{T} Union(T,Nothing}
> >>
> >>
> >>
> >> That allows me to do:
> >>
> >> julia> foo(::Int) = "int"
> >> foo (generic function with 1 method
> >>
> >> julia> foo(::Nothing) = "nothing"
> >> foo (generic function with 2 methods)
> >>
> >> julia> bar(x::Maybe{Int}) = foo(x)
> >> bar (generic function with 1 method)
> >>
> >> julia> foo(1)
> >> "int"
> >>
> >> julia> foo(nothing)
> >> "nothing"
> >>
> >> julia> bar(nothing)
> >> "nothing"
> >>
> >> julia> bar(1)
> >> "int"
> >>
> >>
> >> which seems like what I want.
> >>
> >> HOWEVER, there's also Nullable, described at
> >>
> http://julia.readthedocs.org/en/latest/manual/types/#nullable-types-representing-missing-values
>
> >> and also at
> >>
> http://docs.julialang.org/en/latest/manual/faq/#nothingness-and-missing-values
>
> >> which seems like what I "should" be using. But I can't see how to
> dispatch
> >> on it.
> >>
> >> So it seems like one of the following is true
> >>
> >> 1 - There is a way to dispatch on Nothing, and please someone explain
> it
> >> to me
> >>
> >> 2 - Nullable should be changed so that it can be dispatched on
> >>
> >> 3 - We need Maybe in Base as well as Nothing.
> >>
> >> 1 or 2 sounds fine (although I personally don't see how you can do 2).
> 3
> >> seems like the worst option, but still is presumably better than
> everyone
> >> and their dog defining this type in their own code.
> >>
> >> Any enlightenment appreciated,
> >> Andrew
> >>
> >> PS More references
> >>
> >> https://github.com/JuliaLang/julia/issues/3332
> >>
> >> https://github.com/JuliaLang/julia/issues/1134
> >>
> >> https://github.com/JuliaLang/julia/pull/8152
>