Keyword Arguments and type parameter

I want to ensure some argument value to be zero and to have the same type (Float64, Float32, Int) according to other given arguments. Without keyword argument, I can do this:

function g(a::T = T(0), b::T = T(0)) where T
    println(T)
end

g(1)
# Int64

Then I expect following works as well:

function f(;a::T = T(0), b::T = T(0)) where T
    print(T)
end

f(a=1,b=2)
# Int64

f(a=1)
# UndefVarError: T not defined

This seems strange to me. Is the keyword argument seen as a “whole” type?

My original problem is that I try to define a complex struct using @kwdef, which
includes many “default 0” fields. For example:

@kwdef struct TerrianModifier{T}
    attack::T = T(0)
    defence::T = T(0)
    movement::T = T(0)
end

I found that I must specify a type like TerrianModifier{Float64}(attack=1.0) to create such a struct object, while I expect that TerrianModifier(attack = 1.) is enough.

Maybe explicit {Float64} is the recommended practice? If so, is it possible to specify a default type parameter (ex. Float64)? It seems like TerrianModifier(;kwargs...) = TerrianModifier{Float64}(;kwargs...) works but give a redefinition warning.

I don’t know how to make this interact with @kwdef, but can’t you just promote on construction?

julia> struct Ter{T}
         attack::T
         defence::T
         movement::T
       end
       function Ter(;att=false, def=false, mov=false)
         new = promote(att, def, mov)
         Ter(new...)
       end;

julia> Ter(att=3.5)
Ter{Float64}(3.5, 0.0, 0.0)
2 Likes

Thanks for mentioning promote, I didn’t know it well and checked the document.

My struct includes 60 fields and only part of them require such constraints. So adding a promote with a modified @kwdef seems a solution, while changing the semantic a little.

Besides, the definition of @kwdef is not that easy to read :rofl:.