# Outer constructor for Base.@kwdef with constrained parametric type

**URL:** <https://discourse.julialang.org/t/outer-constructor-for-base-kwdef-with-constrained-parametric-type/65286>\
**Category:** General Usage\
**Created:** [July 26, 2021, 3:58am UTC](https://discourse.julialang.org/t/outer-constructor-for-base-kwdef-with-constrained-parametric-type/65286 "2021-07-26T03:58:32Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Jae-Mo\_Lihm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jae-mo_lihm/32/20145_2.png) [@Jae-Mo\_Lihm](https://discourse.julialang.org/u/Jae-Mo_Lihm)\
**Post date:** [July 26, 2021, 3:58am UTC](https://discourse.julialang.org/t/outer-constructor-for-base-kwdef-with-constrained-parametric-type/65286/1 "2021-07-26T03:58:33Z")

</div>

```julia
julia> Base.@kwdef struct A1{T <: Real}
           n::Int
       end

julia> A1{T}() where {T} = A1{T}(n=3)

julia> Base.@kwdef struct A2{T}
           n::Int
       end

julia> A2{T}() where {T} = A2{T}(n=3)

julia> A1{Float64}()
ERROR: UndefKeywordError: keyword argument n not assigned
Stacktrace:
 [1] A1{Float64}()
   @ Main ./util.jl:462
 [2] top-level scope
   @ REPL[6]:1

julia> A2{Float64}()
A2{Float64}(3)

```

The only difference between `A1` and `A2` is that the constraint `T <: Real` on the type parameter.  
Why does `A1{Float64}()` fail, while `A2{Float64}() does not?

```julia
julia> versioninfo()
Julia Version 1.6.1
Commit 6aaedecc44 (2021-04-23 05:59 UTC)
Platform Info:
  OS: Linux (x86_64-pc-linux-gnu)
  CPU: Intel(R) Xeon(R) CPU E5-2630 v3 @ 2.40GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-11.0.1 (ORCJIT, haswell)
Environment:
  JULIA = /home/jmlim/appl/julia-1.6.1/bin/julia
  JULIA_EDITOR = "/home/jmlim/.vscode-server/bin/c3f126316369cd610563c75b1b1725e0679adfb3/node"
  JULIA_NUM_THREADS = 1

```

---

<div class="post-metadata">

**Author:** ![oheil](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oheil/32/220745_2.png) [@oheil](https://discourse.julialang.org/u/oheil)\
**Post date:** [July 26, 2021, 6:27am UTC](https://discourse.julialang.org/t/outer-constructor-for-base-kwdef-with-constrained-parametric-type/65286/2 "2021-07-26T06:27:06Z")

</div>

I can’t find out the “why” but it works with:

```julia
A1{T}() where {T <: Real } = A1{T}(n=3)

```

---

<div class="post-metadata">

**Author:** ![rfourquet](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rfourquet/32/3610_2.png) [@rfourquet](https://discourse.julialang.org/u/rfourquet)\
**Post date:** [July 26, 2021, 7:45am UTC](https://discourse.julialang.org/t/outer-constructor-for-base-kwdef-with-constrained-parametric-type/65286/3 "2021-07-26T07:45:05Z")

</div>

Using `@kwdef` already defines a method for `A1{T}() where T<:Real`, which requires a keyword, and which is called even when you define a (somewhat less specific) method `A1{T}() = ...`:

```julia
julia> Base.@kwdef struct A1{T <: Real}
           n::Int
       end

julia> methods(A1{Float})
# 2 methods for type constructor:
[1] A1{T}(; n) where T<:Real in Main at util.jl:483
[2] A1{T}(n) where T<:Real in Main at REPL[1]:2

```

(remember that keywords are not dispatched on).
