# Using multiple dispatch with parametric constructors produces ambiguous call

**URL:** <https://discourse.julialang.org/t/using-multiple-dispatch-with-parametric-constructors-produces-ambiguous-call/44295>\
**Category:** General Usage\
**Created:** [August 4, 2020, 11:39pm UTC](https://discourse.julialang.org/t/using-multiple-dispatch-with-parametric-constructors-produces-ambiguous-call/44295 "2020-08-04T23:39:23Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![anon37204545](https://avatars.discourse-cdn.com/v4/letter/a/439d5e/32.png) [@anon37204545](https://discourse.julialang.org/u/anon37204545)\
**Post date:** [August 4, 2020, 11:39pm UTC](https://discourse.julialang.org/t/using-multiple-dispatch-with-parametric-constructors-produces-ambiguous-call/44295/1 "2020-08-04T23:39:23Z")

</div>

This code

```julia
const CompoundTuple{T} = Tuple{Compound{T}, T}

struct ChemEquation{T<:Number}
    tuples::Vector{CompoundTuple{T}}
end
ChemEquation(tuples::Vector{CompoundTuple{T}}) where T = ChemEquation{T}(tuples)

ChemEquation{T}(str::AbstractString) where T = ChemEquation(compoundtuples(str, T))
ChemEquation(str::AbstractString) = ChemEquation{Int}(str)

```

produces this error

```julia
LoadError: LoadError: MethodError: ChemEquation{Int64}(::String) is ambiguous. Candidates:
    (::Type{ChemEquation{T}})(tuples) where T<:Number in ChemEquations at C:\Users\mirav\Documents\dev\julia\ChemEquations.jl\src\chemequation.jl:22
    (::Type{ChemEquation{T}})(str::AbstractString) where T in ChemEquations at C:\Users\mirav\Documents\dev\julia\ChemEquations.jl\src\chemequation.jl:45
  Possible fix, define
    (::Type{ChemEquation{T}})(::AbstractString) where T<:Number

```

with stacktrace pointing to the last line of my code.

Note: removing `ChemEquation(tuples::Vector{CompoundTuple{T}}) where T = ChemEquation{T}(tuples)` doesn’t change anything.

The proposed fix actually works, but I don’t understand why, since `ChemEquation.tuples` is definitely typed. What confuses the multiple dispatch system in this case, and why does the proposed fix work?

---

<div class="post-metadata">

**Author:** ![giordano](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/giordano/32/2166_2.png) [@giordano](https://discourse.julialang.org/u/giordano)\
**Post date:** [August 4, 2020, 11:44pm UTC](https://discourse.julialang.org/t/using-multiple-dispatch-with-parametric-constructors-produces-ambiguous-call/44295/2 "2020-08-04T23:44:41Z")

</div>

If you want to make the life easier for people who want to help you, you’re better off providing a complete code to play with. You don’t define `Compound{T}` and even if I add the line

```julia
struct Compound{T} end

```

I don’t get any error with your code because you just define functions. I assume you get an error when calling one of the constructors. Which one? How do you call it?

---

<div class="post-metadata">

**Author:** ![anon37204545](https://avatars.discourse-cdn.com/v4/letter/a/439d5e/32.png) [@anon37204545](https://discourse.julialang.org/u/anon37204545)\
**Post date:** [August 4, 2020, 11:50pm UTC](https://discourse.julialang.org/t/using-multiple-dispatch-with-parametric-constructors-produces-ambiguous-call/44295/3 "2020-08-04T23:50:51Z")

</div>

Changing `Compound` in `CompoundTuple{T} = Tuple{Compound{T}, T}` to `Complex` for example still produces the same error, so I don’t think `Compound` is the issue. I thought adding that code would bloat the question.

As I noted, the error appears when calling `ChemEquation{Int}(str)`, also unrelated to `Compound`.

`Compound` is just another struct defined in similar manner, but it has two fields, so errors like this one don’t appear.

```julia
const ElementTuple{T} = Tuple{String, T}

struct Compound{T<:Number}
    tuples::Vector{ElementTuple{T}}
    charge::T
end
Compound(tuples::Vector{ElementTuple{T}}, charge::T) where T = Compound{T}(tuples, charge)

Compound{T}(str::AbstractString) where T = Compound(elementtuples(str, T), charge(str, T))
Compound(str::AbstractString) = Compound{Int}(str)

```

---

<div class="post-metadata">

**Author:** ![giordano](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/giordano/32/2166_2.png) [@giordano](https://discourse.julialang.org/u/giordano)\
**Post date:** [August 5, 2020, 10:38pm UTC](https://discourse.julialang.org/t/using-multiple-dispatch-with-parametric-constructors-produces-ambiguous-call/44295/4 "2020-08-05T22:38:57Z")

</div>

> [@anon37204545](#):
>
> I thought adding that code would bloat the question.

Well, it’s pretty much the opposite: if you want help with code, you should very likely provide the code. As little as possible, but working code. See [Please read: make it easier to help you](https://discourse.julialang.org/t/psa-make-it-easier-to-help-you/14757) and [How to create a Minimal, Reproducible Example - Help Center - Stack Overflow](https://stackoverflow.com/help/minimal-reproducible-example). Your code doesn’t define `elementtuples` nor `charge`.

> [@anon37204545](#):
>
> As I noted, the error appears when calling `ChemEquation{Int}(str)` , also unrelated to `Compound` .

I guess you’re now talking about `Compound{Int}(str)` (what is `str`? I assume it’s any string)?

If you want to be helped, providing incomplete code with wrong references is not going to put people in the right mood.

---

<div class="post-metadata">

**Author:** ![anon37204545](https://avatars.discourse-cdn.com/v4/letter/a/439d5e/32.png) [@anon37204545](https://discourse.julialang.org/u/anon37204545)\
**Post date:** [August 5, 2020, 10:51pm UTC](https://discourse.julialang.org/t/using-multiple-dispatch-with-parametric-constructors-produces-ambiguous-call/44295/5 "2020-08-05T22:51:39Z")

</div>

The source code is in [https://github.com/zdroid/ChemEquations.jl](https://github.com/zdroid/ChemEquations.jl), but it has hundreds of lines. I don’t think it contains any useful information, since I identified the error to be something else.

The problem here is that

```julia
struct ChemEquation{T<:Number}
    tuples::Vector{CompoundTuple{T}}
end

```

produces a constructor without definitely typed `tuples`. One fix for that is this:

```julia
struct ChemEquation{T<:Number}
    tuples::Vector{CompoundTuple{T}}
    ChemEquation{T}(tuples::Vector{CompoundTuple{T}}) where T = new{T}(tuples)
end

```

But the explanation in [Parametric constructors docs](https://docs.julialang.org/en/v1/manual/constructors/#Parametric-Constructors-1) is unclear, so I’m asking here for that. Sorry if I wasn’t clear enough.

---

<div class="post-metadata">

**Author:** ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)\
**Post date:** [August 6, 2020, 12:53am UTC](https://discourse.julialang.org/t/using-multiple-dispatch-with-parametric-constructors-produces-ambiguous-call/44295/6 "2020-08-06T00:53:13Z")

</div>

Please post a complete question with complete, minimal working code and example usage which demonstrates current input and output, and desired output – in other words, follow the advice that Mosè already posted by following the PSA document.

If you do that you are likely to get good and useful help. (And if you don’t, you aren’t.)

---

<div class="post-metadata">

**Author:** ![ericphanson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ericphanson/32/215186_2.png) [@ericphanson](https://discourse.julialang.org/u/ericphanson)\
**Post date:** [August 6, 2020, 1:26am UTC](https://discourse.julialang.org/t/using-multiple-dispatch-with-parametric-constructors-produces-ambiguous-call/44295/7 "2020-08-06T01:26:17Z")

</div>

> [@anon37204545](#):
>
> ```julia
> (::Type{ChemEquation{T}})(tuples) where T<:Number in ChemEquations at C:\Users\mirav\Documents\dev\julia\ChemEquations.jl\src\chemequation.jl:22
> 
> ```

For this one, `T <: Number` matches the `Int` parameter in your call; the argument matches too (since it’s `Any` here).

> [@anon37204545](#):
>
> ```julia
> (::Type{ChemEquation{T}})(str::AbstractString) where T in ChemEquations at C:\Users\mirav\Documents\dev\julia\ChemEquations.jl\src\chemequation.jl:45
> 
> ```

For this one, the type of the argument matches the string type in the argument of your call and the parameter `T` matches too (since it’s unconstrained here).

So both match, and one matches narrowly with the type parameter and the other matches narrowly with the argument type; neither method is more specific than the other. So it’s ambiguous.

---

<div class="post-metadata">

**Author:** ![anon37204545](https://avatars.discourse-cdn.com/v4/letter/a/439d5e/32.png) [@anon37204545](https://discourse.julialang.org/u/anon37204545)\
**Post date:** [August 6, 2020, 12:43pm UTC](https://discourse.julialang.org/t/using-multiple-dispatch-with-parametric-constructors-produces-ambiguous-call/44295/8 "2020-08-06T12:43:29Z")

</div>

In which way the previous post doesn’t satisfy those conditions? Nevertheless, I’ve made a simplified example which produces the same error:

```julia
julia> struct Hey{T<:Number}
           a::Vector{T}
       end

julia> Hey{T}(str::AbstractString) where T = Hey{T}(T.(collect(str)))

julia> Hey(str::AbstractString) = Hey{Int}(str)
Hey

julia> Hey("123")
ERROR: MethodError: Hey{Int64}(::String) is ambiguous. Candidates:
  (::Type{Hey{T}})(a) where T<:Number in Main at REPL[1]:2
  (::Type{Hey{T}})(str::AbstractString) where T in Main at REPL[2]:1
Possible fix, define
  (::Type{Hey{T}})(::AbstractString) where T<:Number

```

> [@ericphanson](#):
>
> For this one, the type of the argument matches the string type in the argument of your call and the parameter `T` matches too (since it’s unconstrained here).
> 
> So both match, and one matches narrowly with the type parameter and the other matches narrowly with the argument type; neither method is more specific than the other. So it’s ambiguous.

I understood that, but I’m asking is this desired behavior? It seems illogical, for a **definitely typed** struct field to accept **any type** , instead of any type under parametric conditions (i.e. `T<:Number`).

---

<div class="post-metadata">

**Author:** ![ericphanson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ericphanson/32/215186_2.png) [@ericphanson](https://discourse.julialang.org/u/ericphanson)\
**Post date:** [August 6, 2020, 1:54pm UTC](https://discourse.julialang.org/t/using-multiple-dispatch-with-parametric-constructors-produces-ambiguous-call/44295/9 "2020-08-06T13:54:26Z")

</div>

> [@anon37204545](#):
>
> I understood that, but I’m asking is this desired behavior? It seems illogical, for a **definitely typed** struct field to accept **any type** , instead of any type under parametric conditions (i.e. `T<:Number` ).

Ah, I hadn’t realized that was your question. I’m not sure; I tried

```julia
Hey{T}(str::AbstractString) where T = Hey{Int}(str)

```

to see if you could use this behavior to do a fallback method or something like that, but it errors (`ERROR: TypeError: in Hey, in T, expected T<:Number, got Type{String}`).
