> I know in F# people encourage Discriminated Unions, what about in Julia?
I would say that Julia does not encourage them, but it is fine to use
them.
> I would like to do the following:
>
> immutable B end
> immutable C end
>
> typealias A Union{B,C}
>
> function A(x::Int)
> if x > 0
> B()
> else
> C()
> end
> end
>
> But it doesn't work because I cannot add a constructor for union type?
This works:
julia> function call(::Type{A}, x::Int)if x > 0
B()
else
C()
end
end
call (generic function with 1039 methods)
julia> A(5)
B()
julia> A(-2)
C()
julia> Union{A,B}(6)
B()
(note in 0.5 this currently doesn't work)
> Is Union a preferred way in Julia in this case, or abstract type +
> inheritance is better?
I'm not sure how your example would fit with inheritance.
> Does union type solves the problem of unstable return type from the
> function at all?
julia> @code_typed A(5)
1-element Array{Any,1}:
:($(Expr(:lambda, Any[symbol("#s1"),:x],
Any[Any[Any[symbol("#s1"),Type{Union{B,C}},0],Any[:x,Int64,0]],Any[],Any[],Any[]],
:(begin # none, line 1:
unless (Base.slt_int)(0,x::Int64)::Bool goto 0 # none, line 2:
return $(Expr(:new, :((top(getfield))(Main,:B)::Type{B})))
goto 1
0: # none, line 4:
return $(Expr(:new, :((top(getfield))(Main,:C)::Type{C})))
1:
end::Union{B,C}))))
So, no, not type stable.
Performance is only maximal if Julia can infer a concrete type. Whether
you have a Union or Any does not matter for performance. However,
unless you use something like above `call` method in an hot inner loop,
it will be just fine. (Have you read the performance tips section?)