# Code associated with \`invoke\`

**URL:** <https://discourse.julialang.org/t/code-associated-with-invoke/100109>\
**Category:** General Usage\
**Tags:** question, reflection\
**Created:** [June 9, 2023, 2:56pm UTC](https://discourse.julialang.org/t/code-associated-with-invoke/100109 "2023-06-09T14:56:34Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![willtebbutt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/willtebbutt/32/6790_2.png) [@willtebbutt](https://discourse.julialang.org/u/willtebbutt)\
**Post date:** [June 9, 2023, 2:56pm UTC](https://discourse.julialang.org/t/code-associated-with-invoke/100109/1 "2023-06-09T14:56:34Z")

</div>

Is it possible to obtain the code associated with an `invoke` call?

Specifically, if I were to write:

```julia
sin(5.0)

```

I know that I can get access to one of various representations of the code via `code_lowered`, `code_typed`, etc. What is not clear to me is how I can do the analogous thing for

```julia
invoke(sin, Float64, 5.0)

```

Something like

```julia
@code_lowered invoke(sin, Float64, 5.0)

```

will fail because `invoke` is a built-in, so doesn’t have Julia code associated with it directly.  
Is there a separate piece of functionality that I could use to return the code that `invoke` looks up?

---

<div class="post-metadata">

**Author:** ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)\
**Post date:** [June 9, 2023, 5:23pm UTC](https://discourse.julialang.org/t/code-associated-with-invoke/100109/2 "2023-06-09T17:23:16Z")

</div>

I guess you want `which`:

[https://docs.julialang.org/en/v1/base/base/#Base.which-Tuple{Any,%20Any}](https://docs.julialang.org/en/v1/base/base/#Base.which-Tuple%7BAny,%20Any%7D)

---

<div class="post-metadata">

**Author:** ![mkitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkitti/32/12459_2.png) [@mkitti](https://discourse.julialang.org/u/mkitti)\
**Post date:** [June 9, 2023, 6:50pm UTC](https://discourse.julialang.org/t/code-associated-with-invoke/100109/3 "2023-06-09T18:50:43Z")

</div>

Note what the macro form of `code_lowered` does:

```julia
julia> @macroexpand @code_lowered sin(5.0)
quote
    #= /cache/build/default-amdci4-0/julialang/julia-release-1-dot-9/usr/share/julia/stdlib/v1.9/InteractiveUtils/src/macros.jl:234 =#
    local var"#2#results" = InteractiveUtils.code_lowered(sin, (Base.typesof)(5.0))
    #= /cache/build/default-amdci4-0/julialang/julia-release-1-dot-9/usr/share/julia/stdlib/v1.9/InteractiveUtils/src/macros.jl:235 =#
    if InteractiveUtils.length(var"#2#results") == 1
        var"#2#results"[1]
    else
        var"#2#results"
    end
end

```

Thus, we can get the same information by just passing the types.

```julia
julia> code_lowered(sin, Tuple{Float64})[1]
CodeInfo(
1 ── Core.NewvarNode(:(@_3))
│ Core.NewvarNode(:(y))
│ Core.NewvarNode(:(n))
│ absx = Base.Math.abs(x)
│ %5 = absx
│ %6 = ($(Expr(:static_parameter, 1)))(Base.Math.pi)
│ %7 = %6 / 4
│ %8 = %5 < %7
└─── goto #5 if not %8
2 ── %10 = absx
│ %11 = Base.Math.eps($(Expr(:static_parameter, 1)))
│ %12 = Base.Math.sqrt(%11)
│ %13 = %10 < %12
└─── goto #4 if not %13
3 ── return x
4 ── %16 = Base.Math.sin_kernel(x)
└─── return %16
5 ── %18 = Base.Math.isnan(x)
└─── goto #7 if not %18
6 ── %20 = ($(Expr(:static_parameter, 1)))(Base.Math.NaN)
└─── return %20
7 ── %22 = Base.Math.isinf(x)
└─── goto #9 if not %22
8 ── Base.Math.sin_domain_error(x)
9 ┄─ %25 = Base.Math.rem_pio2_kernel(x)
│ %26 = Base.indexed_iterate(%25, 1)
│ n = Core.getfield(%26, 1)
│ @_3 = Core.getfield(%26, 2)
│ %29 = Base.indexed_iterate(%25, 2, @_3)
│ y = Core.getfield(%29, 1)
│ n = n & 3
│ %32 = n == 0
└─── goto #11 if not %32
10 ─ %34 = Base.Math.sin_kernel(y)
└─── return %34
11 ─ %36 = n == 1
└─── goto #13 if not %36
12 ─ %38 = Base.Math.cos_kernel(y)
└─── return %38
13 ─ %40 = n == 2
└─── goto #15 if not %40
14 ─ %42 = Base.Math.sin_kernel(y)
│ %43 = -%42
└─── return %43
15 ─ %45 = Base.Math.cos_kernel(y)
│ %46 = -%45
└─── return %46
)

```

Note that the procedural form does not need the value of the arguments at all.

I notice that your `invoke` call does not work. Called correctly, the arguments to pass to `code_lowered` should be exactly the same as the first two arguments passed to `invoke`.

```julia
julia> invoke(sin, Float64, 5.0)
ERROR: TypeError: in invoke, expected Type{T} where T<:Tuple, got Type{Float64}
Stacktrace:
 [1] top-level scope
   @ REPL[40]:1

julia> invoke(sin, Tuple{Float64}, 5.0)
-0.9589242746631385

julia> code_lowered(sin, Tuple{Float64});

```

---

<div class="post-metadata">

**Author:** ![willtebbutt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/willtebbutt/32/6790_2.png) [@willtebbutt](https://discourse.julialang.org/u/willtebbutt)\
**Post date:** [June 14, 2023, 9:33am UTC](https://discourse.julialang.org/t/code-associated-with-invoke/100109/4 "2023-06-14T09:33:08Z")

</div>

> I notice that your `invoke` call does not work.

Sorry, yes, you are correct – I messed up the signature of `invoke` slightly. Your version of the call is correct.

> I guess you want `which`:

@nsajko Thanks for this – I feel like it’s nearly what I need, but not quite. Specifically, while it gives me the `Method`, it doesn’t give me the typed-code (optimised and un-optimised) i.e. a `CodeInfo` / `IRCode` object. Do you know if there’s a way to get at that, given the method?

---

<div class="post-metadata">

**Author:** ![willtebbutt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/willtebbutt/32/6790_2.png) [@willtebbutt](https://discourse.julialang.org/u/willtebbutt)\
**Post date:** [June 14, 2023, 9:41am UTC](https://discourse.julialang.org/t/code-associated-with-invoke/100109/5 "2023-06-14T09:41:29Z")

</div>

It looks (I think) like I can use a mix of `Base.code_typed_by_type` and `which` to figure it out though (I’ve broadened the signature to make it a little bit more interesting):

```julia
sig = Tuple{typeof(sin), Real}
m = which(sig)
typed_codes = Base.code_typed_by_type(sig);
typed_code = only(filter(x -> x[1].parent.def === m, typed_codes))

```

I _think_ that the filtering step should only ever return a single bit of lowered code, but I’m not entirely sure.
