# Undefined constructor is executed

**URL:** <https://discourse.julialang.org/t/undefined-constructor-is-executed/4703>\
**Category:** General Usage\
**Created:** [July 6, 2017, 10:12pm UTC](https://discourse.julialang.org/t/undefined-constructor-is-executed/4703 "2017-07-06T22:12:38Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![wsshin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wsshin/32/360_2.png) [@wsshin](https://discourse.julialang.org/u/wsshin)\
**Post date:** [July 6, 2017, 10:12pm UTC](https://discourse.julialang.org/t/undefined-constructor-is-executed/4703/1 "2017-07-06T22:12:38Z")

</div>

Consider the following type:

```julia
julia> VERSION
v"0.6.1-pre.0"

julia> struct MyType{T}
           x::Float64
           y::T
       end

```

According to [this documentation](https://docs.julialang.org/en/latest/manual/constructors/#Parametric-Constructors-1), such type definition implicitly defines an outer constructor `MyType(x::Float64, y::T) where {T} = MyType{T}(x,y)`. Therefore, we can construct a MyType instance as

```julia
julia> MyType(1.0, 2.0)
MyType{Float64}(1.0, 2.0)

```

but passing a non-`Float64` first argument or missing the second argument generates an error:

```julia
julia> MyType(1, 2.0)
ERROR: MethodError: no method matching MyType(::Int64, ::Float64)
Closest candidates are:
  MyType(::Float64, ::T) where T at REPL[1]:2

julia> MyType(1.0)
ERROR: MethodError: Cannot `convert` an object of type Float64 to an object of type MyType
This may have arisen from a call to the constructor MyType(...),
since type constructors fall back to convert methods.
Stacktrace:
 [1] MyType(::Float64) at ./sysimg.jl:24

```

Now, let’s define an additional outer constructor that can handle both the above error-generating cases:

```julia
julia> MyType(x::Real, y::T=nothing) where {T} = (println("Executed"); MyType{T}(x,y))
MyType

```

Note that `"Executed"` must be printed out every time this constructor is executed. If we repeat the above two constructions using this newly defined outer constructor, we get

```julia
julia> MyType(1, 2.0)
Executed
MyType{Float64}(1.0, 2.0)

julia> MyType(1.0)
MyType{Void}(1.0, nothing)

```

Strangely, the second construction does not print out `"Executed"`! A constructor other than the above defined outer constructor seemed to be used here.

A further test:

```julia
julia> MyType(1)
Executed
MyType{Void}(1.0, nothing)

```

This time, `"Executed"` is correctly printed out. So, it seems that the defined outer constructor is used when automatic type conversion from `Int64` to `Float64` for `x` is required, whereas the constructor is not used if a `Float64` `x` is given.

Why is this happening? How can we explain this phenomenon?

---

<div class="post-metadata">

**Author:** ![bkamins](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bkamins/32/208538_2.png) [@bkamins](https://discourse.julialang.org/u/bkamins)\
**Post date:** [July 6, 2017, 10:35pm UTC](https://discourse.julialang.org/t/undefined-constructor-is-executed/4703/3 "2017-07-06T22:35:05Z")

</div>

`MyType(1.0)` translates to `MyType(1.0, nothing)` and implicit outer constructor is called as `Float64` is more specific than `Real`.  
The explanation how optional arguments are handled is given here [https://docs.julialang.org/en/stable/manual/methods/#Note-on-Optional-and-keyword-Arguments-1](https://docs.julialang.org/en/stable/manual/methods/#Note-on-Optional-and-keyword-Arguments-1).

---

<div class="post-metadata">

**Author:** ![bkamins](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bkamins/32/208538_2.png) [@bkamins](https://discourse.julialang.org/u/bkamins)\
**Post date:** [July 6, 2017, 10:45pm UTC](https://discourse.julialang.org/t/undefined-constructor-is-executed/4703/4 "2017-07-06T22:45:53Z")

</div>

And `MyType(1)` translates to `MyType(1, nothing)` and your additional constructor gets called as `Int` is not `Float64`.  
Observe that inner constructor `MyType{T}(x,y)` does not have restrictions on types of arguments and it allows passing `Int` as `x` that gets converted to `Float64` like it would get converted in assignment `x::Float64 = 1`.

---

<div class="post-metadata">

**Author:** ![wsshin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wsshin/32/360_2.png) [@wsshin](https://discourse.julialang.org/u/wsshin)\
**Post date:** [July 7, 2017, 1:27am UTC](https://discourse.julialang.org/t/undefined-constructor-is-executed/4703/5 "2017-07-07T01:27:34Z")

</div>

> [@bkamins](#):
>
> MyType(1.0) translates to MyType(1.0, nothing) and implicit outer constructor is called as Float64 is more specific than Real.  
> The explanation how optional arguments are handled is given here [https://docs.julialang.org/en/stable/manual/methods/#Note-on-Optional-and-keyword-Arguments-1](https://docs.julialang.org/en/stable/manual/methods/#Note-on-Optional-and-keyword-Arguments-1).

OK. I think the following sentence in the documentation you linked is important: “In other words, optional arguments are tied to a function, not to any specific method of that function.” According to that sentence, is this correct explanation?

- When `MyType(1.0)` is called, the optional second argument `nothing` is appended due to the explicit outer constructor `MyType(x::Real, y::T=nothing) where {T} = ...`.
- This results in calling `MyType(1.0, nothing)`. However, the fact that the optional argument is appended due to one constructor does not mean that the body of that constructor is executed, because “optional arguments are tied to a function, not any specific method of the function.”
- Therefore, in this case calling `MyType(1.0)` is equivalent to calling `MyType(1.0, nothing)` separately, which of course invokes the implicit outer constructor that is more specific than the explicit outer constructor.

---

<div class="post-metadata">

**Author:** ![bkamins](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bkamins/32/208538_2.png) [@bkamins](https://discourse.julialang.org/u/bkamins)\
**Post date:** [July 7, 2017, 6:19am UTC](https://discourse.julialang.org/t/undefined-constructor-is-executed/4703/6 "2017-07-07T06:19:35Z")

</div>

The shorter (equivalent to yours) explanation is that definition:

```julia
MyType(x::Real, y::T=nothing) where {T} = (println("Executed"); MyType{T}(x,y))

```

translates to:

```julia
MyType(x::Real, y::T) where {T} = (println("Executed"); MyType{T}(x,y))
MyType(x::Real) = MyType(x, nothing)

```

and the second definition simply calls the most specific `MyType`. You can see this by running `@code_lowered`:

```julia
julia> @code_lowered MyType(1)
CodeInfo(:(begin
        nothing
        return (#self#)(x, Main.nothing)
    end))

julia> @code_lowered MyType(1.0)
CodeInfo(:(begin
        nothing
        return (#self#)(x, Main.nothing)
    end))

julia> @code_lowered MyType(1, nothing)
CodeInfo(:(begin
        nothing
        (Main.println)("Executed")
        return ((Core.apply_type)(Main.MyType, $(Expr(:static_parameter, 1))))(x, y)
    end))

julia> @code_lowered MyType(1.0, nothing)
CodeInfo(:(begin
        nothing
        return ((Core.apply_type)(Main.MyType, $(Expr(:static_parameter, 1))))(x, y)
    end))

```
