# Kwargs in new(), or safer ways of constructing immutable structs

**URL:** <https://discourse.julialang.org/t/kwargs-in-new-or-safer-ways-of-constructing-immutable-structs/43555>\
**Category:** New to Julia\
**Created:** [July 23, 2020, 1:59pm UTC](https://discourse.julialang.org/t/kwargs-in-new-or-safer-ways-of-constructing-immutable-structs/43555 "2020-07-23T13:59:12Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![Benjia](https://avatars.discourse-cdn.com/v4/letter/b/9fc29f/32.png) [@Benjia](https://discourse.julialang.org/u/Benjia)\
**Post date:** [July 23, 2020, 1:59pm UTC](https://discourse.julialang.org/t/kwargs-in-new-or-safer-ways-of-constructing-immutable-structs/43555/1 "2020-07-23T13:59:12Z")

</div>

When creating an immutable struct with a reasonable number of fields and an inner constructor, I find that aligning the arguments to `new()` with the order of the struct fields to be quite tedious and error prone (especially if adjacent fields have the same type, or I add / reorder types). With a mutable struct, I tend to do the following:

```julia
ret = new()
ret.x = x
ret.y = y
ret.z = z
...
return ret

```

Which is much safer and easier to maintain.

Does anyone have a nice approach to this? It seems like `new()` doesn’t support kwargs, but it would be cool if it did. I wonder if a macro could be written that would allow `new()` to take kwargs?

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [July 23, 2020, 2:04pm UTC](https://discourse.julialang.org/t/kwargs-in-new-or-safer-ways-of-constructing-immutable-structs/43555/2 "2020-07-23T14:04:10Z")

</div>

> [@Benjia](#):
>
> I wonder if a macro could be written that would allow `new()` to take kwargs?

Yes, this is something a `@kwnew struct Foo .... end` macro could do.

---

<div class="post-metadata">

**Author:** ![greg\_plowman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/greg_plowman/32/8100_2.png) [@greg\_plowman](https://discourse.julialang.org/u/greg_plowman)\
**Post date:** [July 24, 2020, 4:45am UTC](https://discourse.julialang.org/t/kwargs-in-new-or-safer-ways-of-constructing-immutable-structs/43555/3 "2020-07-24T04:45:57Z")

</div>

Here’s a slight variation on what you asked:

```julia
macro construct(T)
    dataType = Core.eval( __module__ , T)
    esc(Expr(:call, T, fieldnames(dataType)...))
end

struct Foo
    a
    b
    c
    d
end

function Foo(;
    a = nothing,
    b = 1,
    c = [1,2,3],
    d = 3.4
    )
    @construct(Foo)
end

```

```julia
julia> Foo()
Foo(nothing, 1, [1, 2, 3], 3.4)

julia> Foo(b=18)
Foo(nothing, 18, [1, 2, 3], 3.4)

```

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [July 24, 2020, 6:19am UTC](https://discourse.julialang.org/t/kwargs-in-new-or-safer-ways-of-constructing-immutable-structs/43555/4 "2020-07-24T06:19:23Z")

</div>

That said, having a lot of fields in a `struct` may be a code smell.

Reorganizing some of them into smaller `struct`s and then composing is usually worth it.

---

<div class="post-metadata">

**Author:** ![Christian\_Rorvik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/christian_rorvik/32/965_2.png) [@Christian\_Rorvik](https://discourse.julialang.org/u/Christian_Rorvik)\
**Post date:** [July 24, 2020, 7:58am UTC](https://discourse.julialang.org/t/kwargs-in-new-or-safer-ways-of-constructing-immutable-structs/43555/5 "2020-07-24T07:58:01Z")

</div>

Have you looked at [Parameters.jl](https://github.com/mauro3/Parameters.jl)?

---

<div class="post-metadata">

**Author:** ![Benjia](https://avatars.discourse-cdn.com/v4/letter/b/9fc29f/32.png) [@Benjia](https://discourse.julialang.org/u/Benjia)\
**Post date:** [July 24, 2020, 1:53pm UTC](https://discourse.julialang.org/t/kwargs-in-new-or-safer-ways-of-constructing-immutable-structs/43555/6 "2020-07-24T13:53:18Z")

</div>

This is quite creative! And it works fine on the inner constructor by changing `T` to `:new`. I think the implicit naming of all the parameters is actually nicer than having to write out all the argument names as kwargs, which likely have the same names as the arguments anyway.

---

<div class="post-metadata">

**Author:** ![Benjia](https://avatars.discourse-cdn.com/v4/letter/b/9fc29f/32.png) [@Benjia](https://discourse.julialang.org/u/Benjia)\
**Post date:** [July 24, 2020, 1:55pm UTC](https://discourse.julialang.org/t/kwargs-in-new-or-safer-ways-of-constructing-immutable-structs/43555/7 "2020-07-24T13:55:11Z")

</div>

I’ve seen Parameters.jl, though it doesn’t seem to support the kwargs at the level of the inner constructor. Thanks for the help though!

---

<div class="post-metadata">

**Author:** ![Benjia](https://avatars.discourse-cdn.com/v4/letter/b/9fc29f/32.png) [@Benjia](https://discourse.julialang.org/u/Benjia)\
**Post date:** [July 24, 2020, 1:56pm UTC](https://discourse.julialang.org/t/kwargs-in-new-or-safer-ways-of-constructing-immutable-structs/43555/8 "2020-07-24T13:56:25Z")

</div>

Yes, I was waiting for someone to chime in with this… I find these problems arise even with reasonably sized structs, say with 6 or so fields, especially when they all have the same type.

---

<div class="post-metadata">

**Author:** ![Benjia](https://avatars.discourse-cdn.com/v4/letter/b/9fc29f/32.png) [@Benjia](https://discourse.julialang.org/u/Benjia)\
**Post date:** [July 24, 2020, 1:58pm UTC](https://discourse.julialang.org/t/kwargs-in-new-or-safer-ways-of-constructing-immutable-structs/43555/9 "2020-07-24T13:58:01Z")

</div>

I wonder if, when calling a similar macro from an inner constructor, there would even be a way to reach up and automatically get the name of the type without explicitly stating it?

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [July 24, 2020, 2:32pm UTC](https://discourse.julialang.org/t/kwargs-in-new-or-safer-ways-of-constructing-immutable-structs/43555/10 "2020-07-24T14:32:45Z")

</div>

> [@Benjia](#):
>
> especially when they all have the same type

Sorry, I don’t understand what type has to do with this.

---

<div class="post-metadata">

**Author:** ![Benjia](https://avatars.discourse-cdn.com/v4/letter/b/9fc29f/32.png) [@Benjia](https://discourse.julialang.org/u/Benjia)\
**Post date:** [July 24, 2020, 2:42pm UTC](https://discourse.julialang.org/t/kwargs-in-new-or-safer-ways-of-constructing-immutable-structs/43555/11 "2020-07-24T14:42:24Z")

</div>

Having adjacent fields with the same datatype makes a field misordering error silent. If the fields all have unique types, these kinds of errors are detected by the type system.

---

<div class="post-metadata">

**Author:** ![greg\_plowman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/greg_plowman/32/8100_2.png) [@greg\_plowman](https://discourse.julialang.org/u/greg_plowman)\
**Post date:** [July 25, 2020, 7:01am UTC](https://discourse.julialang.org/t/kwargs-in-new-or-safer-ways-of-constructing-immutable-structs/43555/12 "2020-07-25T07:01:22Z")

</div>

> [@Benjia](#):
>
> I wonder if, when calling a similar macro from an inner constructor, there would even be a way to reach up and automatically get the name of the type without explicitly stating it?

I guess part of what I was saying is that maybe you could use outer constructors instead of inner constructors, so then you don’t need `new()`.

If you want default values, then create outer constructor with those values.

When calling a constructor, for most purposes I don’t think you could distinguish between inner and outer constructors?

```julia
macro construct(T)
    dataType = Core.eval( __module__ , T)
    esc(Expr(:call, T, fieldnames(dataType)...))
end

struct Foo
    a
    b
    c
    d
end

function Foo()
    c = [1,2,3]
    a = nothing
    d = 3.4
    b = 1
    @construct(Foo)
end

```

```julia
julia> Foo()
Foo(nothing, 1, [1, 2, 3], 3.4)

```
