# Retrieve kwarg declaration type

**URL:** <https://discourse.julialang.org/t/retrieve-kwarg-declaration-type/49324>\
**Category:** Internals & Design\
**Created:** [October 30, 2020, 7:27pm UTC](https://discourse.julialang.org/t/retrieve-kwarg-declaration-type/49324 "2020-10-30T19:27:42Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Benjia](https://avatars.discourse-cdn.com/v4/letter/b/9fc29f/32.png) [@Benjia](https://discourse.julialang.org/u/Benjia)\
**Post date:** [October 30, 2020, 7:27pm UTC](https://discourse.julialang.org/t/retrieve-kwarg-declaration-type/49324/1 "2020-10-30T19:27:43Z")

</div>

If I define a method:

```julia
f(x; y::Int) = x * y

```

How can I retrieve the `::Int` annotation on `y`, via reflection? I’ve poked around some of the method table properties, but can’t see it anywhere. It’s definitely stored somewhere though, since calling:

```julia
f(3, y=3.0)

```

returns  
`ERROR: TypeError: in keyword argument y, expected **Int64** , got a value of type Float64`

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [October 30, 2020, 7:36pm UTC](https://discourse.julialang.org/t/retrieve-kwarg-declaration-type/49324/2 "2020-10-30T19:36:06Z")

</div>

This?

```julia
julia> f(x :: Int) = x

julia> methods(f)
# 1 method for generic function "f":
[1] f(x::Int64) in Main at REPL[1]:1

```

---

<div class="post-metadata">

**Author:** ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)\
**Post date:** [October 30, 2020, 7:37pm UTC](https://discourse.julialang.org/t/retrieve-kwarg-declaration-type/49324/3 "2020-10-30T19:37:05Z")

</div>

> [@lmiq](#):
>
> ```julia
> julia> f(x :: Int) = x
> 
> julia> methods(f)
> # 1 method for generic function "f":
> [1] f(x::Int64) in Main at REPL[1]:1
> 
> ```

That does not address the OP’s question.

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [October 30, 2020, 7:40pm UTC](https://discourse.julialang.org/t/retrieve-kwarg-declaration-type/49324/4 "2020-10-30T19:40:50Z")

</div>

Ah, you mean because

```julia
julia> f(;x::Int) = x
f (generic function with 1 method)

julia> methods(f)
# 1 method for generic function "f":
[1] f(; x) in Main at REPL[1]:1

```

I didn’t realize that (that the type is not shown there for kwargs).

Sorry.

---

<div class="post-metadata">

**Author:** ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)\
**Post date:** [October 30, 2020, 7:49pm UTC](https://discourse.julialang.org/t/retrieve-kwarg-declaration-type/49324/5 "2020-10-30T19:49:36Z")

</div>

I don’t have a satisfactory answer for you @Benjia, though maybe someone else does.

Poking around, it seems that the method by which julia does type assertion on keyword arguments is very different from those in positional arguments and it’s not exactly easy to find by standard reflection tools. Here’s how you could conceivably do it though:

First, let’s look at what actually happens when you call a function with a keyword argument (it’s more subtle than you might guess!)

```julia
julia> f(x; y::Int) = x * y
f (generic function with 1 method)

julia> g() = f(1; y=3.0)
g (generic function with 1 method)

julia> @code_lowered g()
CodeInfo(
1 ─ %1 = (:y,)
│ %2 = Core.apply_type(Core.NamedTuple, %1)
│ %3 = Core.tuple(3.0)
│ %4 = (%2)(%3)
│ %5 = Core.kwfunc(Main.f)
│ %6 = (%5)(%4, Main.f, 1)
└── return %6
)

```

Okay, so what this says is that `f(1; y=3.0)` is actually doing

```julia
Core.kwfunc(f)(NamedTuple{(:y,)}((3,)), f, 1)

```

Okay, so let’s take a peek inside this call and see what it does:

```julia
julia> @code_lowered Core.kwfunc(f)(NamedTuple{(:y,)}((3,)), f, 1)
CodeInfo(
1 ── %1 = Base.haskey(@_2, :y)
└─── goto #6 if not %1
2 ── %3 = Base.getindex(@_2, :y)
│ %4 = %3 isa Main.Int
└─── goto #4 if not %4
3 ── goto #5
4 ── %7 = %new(Core.TypeError, Symbol("keyword argument"), :y, Main.Int, %3)
└─── Core.throw(%7)
5 ┄─ @_6 = %3
└─── goto #7
6 ── %11 = Core.UndefKeywordError(:y)
└─── @_6 = Core.throw(%11)
7 ┄─ y = @_6
│ %14 = (:y,)
│ %15 = Core.apply_type(Core.NamedTuple, %14)
│ %16 = Base.structdiff(@_2, %15)
│ %17 = Base.pairs(%16)
│ %18 = Base.isempty(%17)
└─── goto #9 if not %18
8 ── goto #10
9 ── Base.kwerr(@_2, @_3, x)
10 ┄ %22 = Main.:(var"#f#69")(y, @_3, x)
└─── return %22
)

```

Yikes. If you spend enough time staring at this, you will see that what this says is that it checks in `y` isa `Int`:

```julia
2 ── %3 = Base.getindex(@_2, :y)
│ %4 = %3 isa Main.Int
└─── goto #4 if not %4
3 ── goto #5

```

and if it’s not an int, then it goes to

```julia
4 ── %7 = %new(Core.TypeError, Symbol("keyword argument"), :y, Main.Int, %3)
└─── Core.throw(%7)

```

which is saying ‘throw an error’. I’m not sure if there’s an automated way to discover this.

---

<div class="post-metadata">

**Author:** ![Benjia](https://avatars.discourse-cdn.com/v4/letter/b/9fc29f/32.png) [@Benjia](https://discourse.julialang.org/u/Benjia)\
**Post date:** [October 30, 2020, 8:19pm UTC](https://discourse.julialang.org/t/retrieve-kwarg-declaration-type/49324/6 "2020-10-30T20:19:47Z")

</div>

Interesting, thanks for going into the detail. It would be quite annoying if this is only stored in the generated function’s code. I could probably parse the CodeInfo, but that seems a bit horrible.
