# How can I build an inner constructor accepting keywords arguments?

**URL:** <https://discourse.julialang.org/t/how-can-i-build-an-inner-constructor-accepting-keywords-arguments/107866>\
**Category:** General Usage\
**Tags:** question\
**Created:** [December 20, 2023, 4:43pm UTC](https://discourse.julialang.org/t/how-can-i-build-an-inner-constructor-accepting-keywords-arguments/107866 "2023-12-20T16:43:09Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Tortar](https://avatars.discourse-cdn.com/v4/letter/t/6bbea6/32.png) [@Tortar](https://discourse.julialang.org/u/Tortar)\
**Post date:** [December 20, 2023, 4:43pm UTC](https://discourse.julialang.org/t/how-can-i-build-an-inner-constructor-accepting-keywords-arguments/107866/1 "2023-12-20T16:43:09Z")

</div>

I show my problem with a minimal example, say I have:

```julia
julia> @kwdef struct Foo
           x::Int = 3
           y::Int
           Foo(m, x, y) = new(m*x, m*y)
           Foo(m; x, y) = Foo(m, x, y)
       end
Foo

```

I’d like to expose only the two inner constructor I have inside the `Foo` definition and nothing else, unfortunately this doesn’t completely work:

```julia
julia> Foo(1, 2, 3)
Foo(2, 3)

julia> Foo(1; y=3)
ERROR: UndefKeywordError: keyword argument `x` not assigned
Stacktrace:
 [1] top-level scope
   @ REPL[5]:1

```

How can I expose those two constructor (and no others)? The second constructor doesn’t seem to play well with the `@kwdef` macro, but I hope there is a solution

---

<div class="post-metadata">

**Author:** ![PetrKryslUCSD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petrkryslucsd/32/215825_2.png) [@PetrKryslUCSD](https://discourse.julialang.org/u/PetrKryslUCSD)\
**Post date:** [December 20, 2023, 5:00pm UTC](https://discourse.julialang.org/t/how-can-i-build-an-inner-constructor-accepting-keywords-arguments/107866/2 "2023-12-20T17:00:15Z")

</div>

What is `m`?

---

<div class="post-metadata">

**Author:** ![Tortar](https://avatars.discourse-cdn.com/v4/letter/t/6bbea6/32.png) [@Tortar](https://discourse.julialang.org/u/Tortar)\
**Post date:** [December 20, 2023, 5:03pm UTC](https://discourse.julialang.org/t/how-can-i-build-an-inner-constructor-accepting-keywords-arguments/107866/3 "2023-12-20T17:03:36Z")

</div>

`m` in the real code is a model which decides what values for x and y are given

Indeed a better example could be

```julia
@kwdef struct Foo
           x::Int = 3
           y::Int
           Foo(m, x, y) = new(m*x, m*y)
           Foo(m; x, y) = Foo(m, x, y)
       end

```

so that `m` is actually used

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [December 20, 2023, 5:07pm UTC](https://discourse.julialang.org/t/how-can-i-build-an-inner-constructor-accepting-keywords-arguments/107866/4 "2023-12-20T17:07:36Z")

</div>

This problem is unrelated to constructors. You haven’t provided any default value for `x` in the constructor.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [December 20, 2023, 5:11pm UTC](https://discourse.julialang.org/t/how-can-i-build-an-inner-constructor-accepting-keywords-arguments/107866/5 "2023-12-20T17:11:10Z")

</div>

Well, actually, I’m not that familiar with `@kwdef`, and dislike that interface, but that seems to be the error given.

If you are going to define a kwargs interface to the type construction anyway, I would personally set the defaults in the constructor and avoid the macro.

---

<div class="post-metadata">

**Author:** ![Tortar](https://avatars.discourse-cdn.com/v4/letter/t/6bbea6/32.png) [@Tortar](https://discourse.julialang.org/u/Tortar)\
**Post date:** [December 20, 2023, 5:13pm UTC](https://discourse.julialang.org/t/how-can-i-build-an-inner-constructor-accepting-keywords-arguments/107866/6 "2023-12-20T17:13:07Z")

</div>

yes, you are right, I think that I should use something like

```julia
struct Foo
    x::Int
    y::Int
    Foo(m, x, y) = new(m*x, m*y)
    Foo(m; x = 3, y) = Foo(m, x, y)
end

```

which seems to work fine:

```julia
julia> Foo(1, 2, 3)
Foo(2, 3)

julia> Foo(1; x=2, y=3)
Foo(2, 3)

julia> Foo(1; y=3)
Foo(3, 3)

```

In my actual problem I have to generate these things with a macro from a different syntax, so I hoped there was something simpler, but this isn’t actually that bad, thank you a lot!
