Default values for composite types in Julia

In C++11, one can initialize the fields of a class to avoid boiler plate code. In Julia, I am currently typing every single combination of constructors in order to handle default values, for example:

immutable GaussianVariogram{T<:Real}
  sill::T
  range::T
  nugget::T
end
GaussianVariogram{T<:Real}(s::T, r::T) = GaussianVariogram(s, r, zero(T))
GaussianVariogram() = GaussianVariogram(1.,1.)

Is there a better mechanism for setting default values? Ideally, something like:

immutable GaussianVariogram{T<:Real}
  sill::T -> one(T)
  range::T -> one(T)
  nugget::T -> zero(T)
end
1 Like

Look at Parameters.jl. It has a macro for exactly what you need.

Sooner or later that will be part of Base in some form I think.

3 Likes

On the spot @ChrisRackauckas, thanks. It would be great to have this as part of the syntax though, agree?

Yes. But until someone makes that happen, this is not a bad solution.

1 Like

The solution doesn’t work with parameters though:

https://github.com/mauro3/Parameters.jl/issues/32

1 Like

Well, your example is fundamentally impossible.

immutable GaussianVariogram{T<:Real}
  sill::T -> one(T)
  range::T -> one(T)
  nugget::T -> zero(T)
end

You specify nowhere what T is, so how is it supposed to know? (In that setup, you want those all UInt128, right?) At least one default must determine T, otherwise there’s no way to know what it means.

But let’s say you do fix the example:

immutable GaussianVariogram{T<:Real}
  sill::T -> 1.0
  range::T -> one(T)
  nugget::T -> zero(T)
end

Anything that uses keyword arguments won’t dispatch, so if keyword arguments are used for the defaults it will not be type stable if you want to have a type parameter. Keyword argument dispatch will be a thing “soon”, so Parameters.jl will be able to handle that in the future, but for now you just have to live with it. That PR is really far along (it’s the one with NamedTuples) and it keeps getting mentioned, so I really think it will be 1.0 material. So I would just design with that in mind.

Default arguments are not a good option though because then the order matters. But if you want the default argument approach, then that’s easy to do by hand:

GaussianVariogram(sill=1.0,range=one(typeof(sill)),nugget=one(typeof(sill)) = GaussianVariogram(sill,range,nugget)

which is fine and type-inferable.

2 Likes

Awesome @ChrisRackauckas, I am definitely sticking with Parameters.jl, and hoping it will be part of the language with additional syntax.

For reference, here’s the Julialang issue which is discussing adding this:

https://github.com/JuliaLang/julia/issues/10146

Your point with wanting type parameters to work is definitely interesting and should be discussed.

3 Likes

Why don’t you put the default values on the constructor function? Like:

struct hello
    saludo::String
    function hello(arg = "oi")
        new(arg)
    end
end