# Recursive \`@code\_lowered\`

**URL:** <https://discourse.julialang.org/t/recursive-code-lowered/17638>\
**Category:** General Usage\
**Created:** [November 17, 2018, 11:06am UTC](https://discourse.julialang.org/t/recursive-code-lowered/17638 "2018-11-17T11:06:07Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![dfdx](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dfdx/32/120_2.png) [@dfdx](https://discourse.julialang.org/u/dfdx)\
**Post date:** [November 17, 2018, 11:06am UTC](https://discourse.julialang.org/t/recursive-code-lowered/17638/1 "2018-11-17T11:06:07Z")

</div>

We can get IR for a single call using `@code_lowered`:

```julia
foo(x) = x + 1
bar(x) = 2 * foo(x)

@code_lowered bar(2.0)

# CodeInfo(
# 1 1 ─ %1 = (Main.foo)(x) │
# │ %2 = 2 * %1 │
# └── return %2 │
# )

```

But how can I dive deeper and get IR for a called function , e.g. `Main.foo(x)`?

---

<div class="post-metadata">

**Author:** ![Elrod](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/elrod/32/22461_2.png) [@Elrod](https://discourse.julialang.org/u/Elrod)\
**Post date:** [November 17, 2018, 6:50pm UTC](https://discourse.julialang.org/t/recursive-code-lowered/17638/2 "2018-11-17T18:50:04Z")

</div>

Unfortunately, [Sugar](https://github.com/SimonDanisch/Sugar.jl) still doesn’t support Julia 1.0, but perhaps following their approach + MacroTools / similar to walk the expressions?

You would need code\_typed + type stable functions, though. Otherwise, if there are different method definitions for `Main.foo`, which do you expand?

---

<div class="post-metadata">

**Author:** ![jrevels](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jrevels/32/10393_2.png) [@jrevels](https://discourse.julialang.org/u/jrevels)\
**Post date:** [November 17, 2018, 11:06pm UTC](https://discourse.julialang.org/t/recursive-code-lowered/17638/3 "2018-11-17T23:06:11Z")

</div>

Do you desire this for debugging or code transformation?

This kind of “recursive reflection” is exactly how [Cassette](https://github.com/jrevels/Cassette.jl) works; you might be interesting in [https://jrevels.github.io/Cassette.jl/latest/contextualpass.html](https://jrevels.github.io/Cassette.jl/latest/contextualpass.html).

Even if you’re only using it for debugging, you can add side effects to an otherwise “no-op” Cassette pass just to e.g. print out the `CodeInfo`.

If you’re fine with doing things manually and just want a quicker interactive workflow, I find [GitHub - timholy/Rebugger.jl: An expression-level debugger for Julia with a provocative command-line (REPL) user interface](https://github.com/timholy/Rebugger.jl) is helpful for this sort of thing.

---

<div class="post-metadata">

**Author:** ![dfdx](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dfdx/32/120_2.png) [@dfdx](https://discourse.julialang.org/u/dfdx)\
**Post date:** [November 18, 2018, 12:49am UTC](https://discourse.julialang.org/t/recursive-code-lowered/17638/4 "2018-11-18T00:49:14Z")

</div>

Ah, how could I forget about it! I used Sugar a number of times to find original source code, but totally forgot that it works with IR even better. Thanks for this reminder!

---

<div class="post-metadata">

**Author:** ![dfdx](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dfdx/32/120_2.png) [@dfdx](https://discourse.julialang.org/u/dfdx)\
**Post date:** [November 18, 2018, 1:08am UTC](https://discourse.julialang.org/t/recursive-code-lowered/17638/5 "2018-11-18T01:08:51Z")

</div>

It’s for code transformation. In fact, I’m trying to estimate effort required to implement something like Zygote or Capstan, but simpler (I’m trying to make a huge focus on simplicity these days, even trading it for a number of features). My latest beast in AD zoo is [Yota.jl](https://github.com/dfdx/Yota.jl) which is based on old school method dispatching (very much like ReverseDiff), but maybe it’s time step forward in complexity again.

I tried Cassette like 3 or 4 times, mostly before Julia 1.0, but then it was too much of a moving target for me to rely on it. Now I still see a disclaimer it its docs:

> For now, **each individual version of Cassette can technically only support a single specific version of Julia at a time** ; differing by even a patch version could (theoretically) break Cassette entirely.

> Cassette enables interaction with many parts of the Julia compiler, a lot of which are undocumented or sparsely documented.

Is API and runtime of Cassette stable enough for somebody not involved into development of Julia compiler or Cassette itself to implement AD on top of it?

---

<div class="post-metadata">

**Author:** ![jrevels](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jrevels/32/10393_2.png) [@jrevels](https://discourse.julialang.org/u/jrevels)\
**Post date:** [November 18, 2018, 1:20am UTC](https://discourse.julialang.org/t/recursive-code-lowered/17638/6 "2018-11-18T01:20:37Z")

</div>

> [@dfdx](#):
>
> My latest beast in AD zoo is [Yota.jl](https://github.com/dfdx/Yota.jl) which is based on old school method dispatching (very much like ReverseDiff), but maybe it’s time step forward in complexity again.

Ooh, cool, I’ll check it out!

> [@dfdx](#):
>
> Now I still see a disclaimer it its docs:

Actually, that specific disclaimer is now out of date, since Base Julia has committed to reverse-dependency testing before new releases (which will catch compiler changes that affect Cassette, so we can patch things ahead of time). I’ll update that when I get the chance.

> Is API and runtime of Cassette stable enough for somebody not involved into development of Julia compiler or Cassette itself to implement AD on top of it?

The documented API (basically, everything but the “contextual tagging” stuff) is stable. Performance is fairly good these days in a lot of cases, though we know of some edge cases. Stressing it on real code is the best way to find those edge cases, of course 🙂 Feel free to ping me if you have questions!

---

<div class="post-metadata">

**Author:** ![dfdx](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dfdx/32/120_2.png) [@dfdx](https://discourse.julialang.org/u/dfdx)\
**Post date:** [November 18, 2018, 9:11pm UTC](https://discourse.julialang.org/t/recursive-code-lowered/17638/7 "2018-11-18T21:11:15Z")

</div>

Sounds promising, thanks! Perhaps this is indeed the way to go.

I guess for AD-like stuff I need to tag functions arguments, but the corresponding [part of manual](https://jrevels.github.io/Cassette.jl/latest/contextualtagging.html) isn’t available. What is the most recent write up on the topic besides [source](https://github.com/jrevels/Cassette.jl/blob/master/src/tagging.jl) and [tests](https://github.com/jrevels/Cassette.jl/blob/master/test/misctaggingtests.jl)? Even if not up to date, it might be useful to read it for better conceptual view.
