On Fri, May 29, 2015 at 3:20 PM, andrew cooke <[email protected]> wrote:
> 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]> 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.

If the user can really return anything, they might also return Nullable
as something. It is probably not a problem if your user never want to
do that though.

>
> 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

Reply via email to