User-Defined Struct Constructors similar to Named Tuples

When initializing user-define objects or structs, I find that he positional argument approach isn’t very clean. For example, let us say that we first start with

mutable struct MyPoint
x::Float64
z::Float64
end

Then as we continue to work, we find that we need a new field “y”
mutable struct MyPoint
x::Float64
y::Float64
z::Float64
end

If we use the constructor method of MyPoint(x,y,z), we then have to change the code whenever there is an assignment to make sure z is not assigned to y. A cheap workaround I’ve used is the following

mutable struct MyPoint
x::Float64
z::Float64
MyPoint(T) = new(T.x, T.z)
end

This allows you to assign the point using a Named Tuple like this
MyPoint((x=1,z=2))

My question is that, would it break anything if we made the default behaviour of struct construction something like
MyPoint(x=1, z=2)

We already have that behavior for Named Tuples, is there something that inhibits us from making user defined structs behave this way too?

You should check out https://github.com/mauro3/Parameters.jl or @kwdef which is in Base.

3 Likes

Note that the only way one can find the documentation on @kwdef is to type ?Base.@kwdef into the REPL. I can’t seem to find Base.@kwdef in the online docs. Also note that @kwdef is not exported from Base, so you will need to use Base.@kwdef or bring it into scope via

using Base: @kwdef

or

import Base.@kwdef

2 Likes

Oh my goodness! Base.@kwdef is EXACTLY what I was looking for. It was MORE than I was looking for! This definitely needs to show up in the Composite Types (https://docs.julialang.org/en/v1/manual/types/#Composite-Types-1) and Constructors (https://docs.julialang.org/en/v1/manual/constructors/) section in the manual.

Goodnes, you have no idea how much this helps me. I’m trying to run a customized variant of the Extended Kalman Filter, and state space models have at least 6 parameters; two of which are functions.

2 Likes