# Typed keyword vararg

**URL:** <https://discourse.julialang.org/t/typed-keyword-vararg/26961>\
**Category:** General Usage\
**Created:** [July 29, 2019, 11:45pm UTC](https://discourse.julialang.org/t/typed-keyword-vararg/26961 "2019-07-29T23:45:56Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Qiyamah](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/qiyamah/32/2660_2.png) [@Qiyamah](https://discourse.julialang.org/u/Qiyamah)\
**Post date:** [July 29, 2019, 11:45pm UTC](https://discourse.julialang.org/t/typed-keyword-vararg/26961/1 "2019-07-29T23:45:56Z")

</div>

```julia
g(;kwargs::Int...) = println(kwargs)

julia> g(x=1,y=2)
ERROR: MethodError: no method matching #g#16(::Base.Iterators.Pairs{Symbol,Int64,Tuple{Symbol,Symbol},NamedTuple{(:x, :y),Tuple{Int64,Int64}}}, ::typeof(g))
Closest candidates are:
  #g#16(::Int64, ::Any) at none:1
Stacktrace:
 [1] (::getfield(Main, Symbol("#kw##g")))(::NamedTuple{(:x, :y),Tuple{Int64,Int64}}, ::typeof(g)) at ./none:0
 [2] top-level scope at none:0

```

can’t I have an typed keyword vararg?

Thanks

---

<div class="post-metadata">

**Author:** ![kevbonham](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kevbonham/32/216165_2.png) [@kevbonham](https://discourse.julialang.org/u/kevbonham)\
**Post date:** [July 30, 2019, 1:11am UTC](https://discourse.julialang.org/t/typed-keyword-vararg/26961/2 "2019-07-30T01:11:04Z")

</div>

I don’t know the answer, but here’s an [old stack overflow question](https://stackoverflow.com/questions/39240527/typed-kwargs-in-julia). The workings of kwargs have changed since then though, so I don’t know if it’s still relevant, but at the time this wasn’t possible.

[The manual still says](https://docs.julialang.org/en/v1/manual/methods/#Note-on-Optional-and-keyword-Arguments-1) that kwargs don’t participate in dispatch, so you might achieve the same ends by just checking in the body of the function

---

<div class="post-metadata">

**Author:** ![shilu1984](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/shilu1984/32/9512_2.png) [@shilu1984](https://discourse.julialang.org/u/shilu1984)\
**Post date:** [July 30, 2019, 3:22am UTC](https://discourse.julialang.org/t/typed-keyword-vararg/26961/3 "2019-07-30T03:22:36Z")

</div>

We know here that the type of kwargs is Iterator.Pairs; therefore, it can not be restrict to type Int.  
I think the feasible way should be:  
`g(;kwargs::T...) where {T<:AbstractDict{Symbol, Int}} = println(kwargs)`  
test:

```julia
julia> g(x=1, y=2, z=3)
Base.Iterators.Pairs(:x=>1,:y=>2,:z=>3)

julia> g(x=1, y=2.5)
ERROR: MethodError: no method matching #g#3(::Base.Iterators.Pairs{Symbol,Real,Tuple{Symbol,Symbol},NamedTuple{(:x, :y),Tuple{Int64,Float64}}}, ::typeof(g))
Closest candidates are:
  #g#3(::T<:AbstractDict{Symbol,Int64}, ::Any) where T<:AbstractDict{Symbol,Int64} at REPL[1]:1
Stacktrace:
 [1] (::getfield(Main, Symbol("#kw##g")))(::NamedTuple{(:x, :y),Tuple{Int64,Float64}}, ::typeof(g)) at .\none:0
 [2] top-level scope at none:0

julia>

```

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [July 30, 2019, 9:17am UTC](https://discourse.julialang.org/t/typed-keyword-vararg/26961/4 "2019-07-30T09:17:03Z")

</div>

this looks a bit convoluted. It’s not like you can pass non-`AbstractDict` to kwargs right?

---

<div class="post-metadata">

**Author:** ![Qiyamah](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/qiyamah/32/2660_2.png) [@Qiyamah](https://discourse.julialang.org/u/Qiyamah)\
**Post date:** [July 30, 2019, 10:03pm UTC](https://discourse.julialang.org/t/typed-keyword-vararg/26961/5 "2019-07-30T22:03:41Z")

</div>

you can but you have do this like  
f(;dict…)

---

<div class="post-metadata">

**Author:** ![JeffreySarnoff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeffreysarnoff/32/1980_2.png) [@JeffreySarnoff](https://discourse.julialang.org/u/JeffreySarnoff)\
**Post date:** [July 30, 2019, 10:47pm UTC](https://discourse.julialang.org/t/typed-keyword-vararg/26961/6 "2019-07-30T22:47:22Z")

</div>

> [@shilu1984](#):
>
> g(;kwargs::T…) where {T\<:AbstractDict{Symbol, Int}} = println(kwargs)

Is there a way to do this with more than one type of kwarg?

---

<div class="post-metadata">

**Author:** ![shilu1984](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/shilu1984/32/9512_2.png) [@shilu1984](https://discourse.julialang.org/u/shilu1984)\
**Post date:** [July 31, 2019, 2:22am UTC](https://discourse.julialang.org/t/typed-keyword-vararg/26961/7 "2019-07-31T02:22:10Z")

</div>

If the type of kwargs is more than one, the second parameter of `AbstractDict` should be a abstract type that are the supertype of kwargs’ type; such as `AbstractDict{Symbol, Real}` for `g(x=1.0, y=1)`.

If the type of the keywords is more arbitrary, there is no need to add a parameter type `Abstract{Symbol, Any}`. After all, function keywords do not participate in the dispatch.

Further, not adding keyword type does not affect the speed of the function, as long as the set of keyword parameters has been run once (compiled).

---

<div class="post-metadata">

**Author:** ![Qiyamah](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/qiyamah/32/2660_2.png) [@Qiyamah](https://discourse.julialang.org/u/Qiyamah)\
**Post date:** [July 31, 2019, 10:17pm UTC](https://discourse.julialang.org/t/typed-keyword-vararg/26961/8 "2019-07-31T22:17:38Z")

</div>

However there is an issue:

```julia
julia> handle_kva(d::D) where {D<:AbstractDict{Symbol,T}} where T = println(d)
handle_kva (generic function with 1 method)

julia> f(;kwargs...) = handle_kva(kwargs)
f (generic function with 1 method)

julia> f(;x=1)
Base.Iterators.Pairs(:x=>1)

julia> f()
ERROR: MethodError: no method matching handle_kva(::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}})
Closest candidates are:
  handle_kva(::D<:AbstractDict{Symbol,T}) where {T, D<:AbstractDict{Symbol,T}} at REPL[1]:1
Stacktrace:
 [1] #f#3(::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}, ::Function) at ./REPL[2]:1
 [2] f() at ./REPL[2]:1
 [3] top-level scope at none:0

```

I assume you can solve it by handle\_kva(d::D) where {D\<:AbstractDict{M,T}} where {M,T} = Dict{Symbol,Any}()

but still It would be awesome to solve it on the function signature.

---

<div class="post-metadata">

**Author:** ![shilu1984](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/shilu1984/32/9512_2.png) [@shilu1984](https://discourse.julialang.org/u/shilu1984)\
**Post date:** [August 1, 2019, 7:54am UTC](https://discourse.julialang.org/t/typed-keyword-vararg/26961/9 "2019-08-01T07:54:22Z")

</div>

Is your question about the exception of empty keyword parameter?

I test that the type of kwargs is subtype of `AbstractDict{Union{}, Union{}}` where keyword parameter is empty. So may be `Union{AbstractDict{Union{}, Union{}}, AbstractDict{Symbol, Int}}` could be used to consider the exception.

Wow, this type expression looks very long.
