# Keyword Arguments and type parameter

**URL:** https://discourse.julialang.org/t/keyword-arguments-and-type-parameter/38920
**Category:** New to Julia
**Created:** [May 6, 2020, 11:03pm UTC](https://discourse.julialang.org/t/keyword-arguments-and-type-parameter/38920 "2020-05-06T23:03:26Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![yiyuezhuo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yiyuezhuo/32/27101_2.png) [@yiyuezhuo](https://discourse.julialang.org/u/yiyuezhuo)
#### Post date: [May 6, 2020, 11:03pm UTC](https://discourse.julialang.org/t/keyword-arguments-and-type-parameter/38920/1 "2020-05-06T23:03:27Z")

</div>

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:

```julia
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:

```julia
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:

```julia
@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.

---

<div class="post-metadata">

### Author: ![mcabbott](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mcabbott/32/6603_2.png) [@mcabbott](https://discourse.julialang.org/u/mcabbott)
#### Post date: [May 6, 2020, 11:21pm UTC](https://discourse.julialang.org/t/keyword-arguments-and-type-parameter/38920/2 "2020-05-06T23:21:10Z")

</div>

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

```julia
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)

```

---

<div class="post-metadata">

### Author: ![yiyuezhuo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yiyuezhuo/32/27101_2.png) [@yiyuezhuo](https://discourse.julialang.org/u/yiyuezhuo)
#### Post date: [May 6, 2020, 11:57pm UTC](https://discourse.julialang.org/t/keyword-arguments-and-type-parameter/38920/3 "2020-05-06T23:57:43Z")

</div>

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 🤣.
