# Function signature doesn't match when using Union

**URL:** <https://discourse.julialang.org/t/function-signature-doesnt-match-when-using-union/11268>\
**Category:** General Usage\
**Created:** [May 30, 2018, 5:31pm UTC](https://discourse.julialang.org/t/function-signature-doesnt-match-when-using-union/11268 "2018-05-30T17:31:25Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![bluesmoon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bluesmoon/32/327_2.png) [@bluesmoon](https://discourse.julialang.org/u/bluesmoon)\
**Post date:** [May 30, 2018, 5:31pm UTC](https://discourse.julialang.org/t/function-signature-doesnt-match-when-using-union/11268/1 "2018-05-30T17:31:25Z")

</div>

Using julia 0.6.3-pre.2 (built from git), I tried the following:

```julia
julia> foo_bar{T<:Union{AbstractString, Symbol}}(d::Union{Symbol, AbstractVector{T}}=AbstractString[]) = "OK"
foo_bar (generic function with 2 methods)

julia> foo_bar()
"OK"

julia> foo_bar([:abc])
"OK"

julia> foo_bar(["abc"])
"OK"

julia> foo_bar(Union{AbstractString, Symbol}["abc", :abc])
"OK"

julia> foo_bar(:abc)
ERROR: MethodError: no method matching foo_bar(::Symbol)
Closest candidates are:
  foo_bar(::Union{AbstractArray{T<:Union{AbstractString, Symbol},1}, Symbol}) where T<:Union{AbstractString, Symbol} at REPL[1]:1
  foo_bar() at REPL[1]:1

julia> 

```

So my question is why doesn’t `Symbol` match `Union{AbstractArray{T<:Union{AbstractString, Symbol},1}, Symbol}`?

I’ve also noticed that if I define my function like this:

```julia
foo_bar{T<:Union{AbstractString, Symbol}}(d::Union{T, AbstractVector{T}}=AbstractString[]) = "OK"

```

Then it correctly matches, but then it also matches `foo_bar("abc")`

I know the best option would be to define different function signatures, but in the code that I’m using, this is a keyword argument, and for backwards compatibility with our legacy code, we need to support the old `Symbol` method.

Thanks,

Philip

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [May 30, 2018, 5:44pm UTC](https://discourse.julialang.org/t/function-signature-doesnt-match-when-using-union/11268/2 "2018-05-30T17:44:33Z")

</div>

The problem is that when you pass in just a Symbol argument, the type-variable `T` is not defined. Julia v0.6 won’t let you do that, because it requires that all type-variables must have defined values in order for a method to match.

Julia v0.7 removes that requirement, so your example will just work in the future:

```julia
julia> foo_bar(d::Union{Symbol, AbstractVector{T}}=AbstractString[]) where {T <: Union{AbstractString, Symbol}} = "OK"
foo_bar (generic function with 2 methods)

julia> foo_bar(:a)
"OK"

```

(as long as you don’t actually refer to `T` inside the body of your function, since `T` is still not defined when you pass in a `Symbol`).

If you don’t actually need `T` at all inside the function, then you can make this work on v0.6 and v0.7 by using the `AbstractVector{<:Foo}` construction instead:

```julia
julia> foo_bar(d::Union{Symbol, AbstractVector{<:Union{AbstractString, Symbol}}}=AbstractString[]) = "OK"
foo_bar (generic function with 2 methods)

julia> foo_bar(:a)
"OK"

```

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [May 30, 2018, 5:45pm UTC](https://discourse.julialang.org/t/function-signature-doesnt-match-when-using-union/11268/3 "2018-05-30T17:45:20Z")

</div>

```julia
julia> foo_bar(d::Union{Symbol, AbstractVector{<:Union{AbstractString, Symbol}}}=AbstractString[]) = "OK"
foo_bar (generic function with 2 methods)

julia> foo_bar()
"OK"

julia> foo_bar([:abc])
"OK"

julia> foo_bar(["abc"])
"OK"

julia> foo_bar(:abc)
"OK"

```

Edit: Sniped.

---

<div class="post-metadata">

**Author:** ![bluesmoon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bluesmoon/32/327_2.png) [@bluesmoon](https://discourse.julialang.org/u/bluesmoon)\
**Post date:** [May 30, 2018, 6:43pm UTC](https://discourse.julialang.org/t/function-signature-doesnt-match-when-using-union/11268/4 "2018-05-30T18:43:58Z")

</div>

Thanks, makes sense and works, though not in 0.4, and I need to figure that out still (legacy code and all that)
