# Using \`@overlay\` like Cassette.jl?

**URL:** <https://discourse.julialang.org/t/using-overlay-like-cassette-jl/124700>\
**Category:** General Usage\
**Tags:** question\
**Created:** [January 12, 2025, 4:16pm UTC](https://discourse.julialang.org/t/using-overlay-like-cassette-jl/124700 "2025-01-12T16:16:51Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![MilesCranmer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/milescranmer/32/21070_2.png) [@MilesCranmer](https://discourse.julialang.org/u/MilesCranmer)\
**Post date:** [January 12, 2025, 4:16pm UTC](https://discourse.julialang.org/t/using-overlay-like-cassette-jl/124700/1 "2025-01-12T16:16:51Z")

</div>

I was wondering if anybody knew if it is possible to use `Base.Experimental.@overlay` in a way similar the overdubbing feature of Cassette.jl? In particular, I want to override the behavior of every single function compiled, rather than only a few explicitly-listed methods.

Sadly it seems like Cassette.jl is unmaintained these days so I’ve been [hunting for an alternative](https://discourse.julialang.org/t/contextual-dispatch-on-julia-1-12/124535). I found `Base.Experimental.@overlay` alongside this “MiniCassette” in the Compiler test suite: [julia/Compiler/test/contextual.jl at 71bfbb3b0134c05e1af49c385738b8f5d8f06e7c · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/blob/71bfbb3b0134c05e1af49c385738b8f5d8f06e7c/Compiler/test/contextual.jl#L10-L110). However, I was unable to repurpose this working for general overdubbing. I tried the following:

```julia
julia> import .MiniCassette: overdub

julia> f(x) = sin(x)
f (generic function with 1 method)

julia> @eval function overdub(ctx::Ctx, f, args...)
           $(Expr(:meta, :generated_only))
           f in (sin, f) && println("Calling from ", f, " with args ", args)
           $(Expr(:meta, :generated, MiniCassette.overdub_generator))
       end
overdub (generic function with 3 methods)

```

Basically seeing if I can inject this print statement into `sin` and `f` via a conditional. However, it seems MiniCassette is not set up for that, as it gave me this error:

```julia
julia> overdub(Ctx(), f, 1.0)
ERROR: AssertionError: !(mi.def.isva)
Stacktrace:

```

Whereas my desired output would be:

```plaintext
Calling from sin with args (1.0,)
Calling from f with args (1.0,)

```

Does anybody have any advice for getting Cassette-like overdubbing on 1.12? Again, I want to overdub _all_ functions (it’s for BorrowChecker.jl), so I cannot explicitly declare all methods in a method table.

Tagging some people I see with commits to that file… @aviatesk @Oscar_Smith @maleadt @jameson. Any tips for getting something like this this?

---

<div class="post-metadata">

**Author:** ![cjdoris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cjdoris/32/213133_2.png) [@cjdoris](https://discourse.julialang.org/u/cjdoris)\
**Post date:** [January 12, 2025, 7:18pm UTC](https://discourse.julialang.org/t/using-overlay-like-cassette-jl/124700/2 "2025-01-12T19:18:59Z")

</div>

Aside, what is `@overlay`? It’s not in the docs.

---

<div class="post-metadata">

**Author:** ![MilesCranmer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/milescranmer/32/21070_2.png) [@MilesCranmer](https://discourse.julialang.org/u/MilesCranmer)\
**Post date:** [January 12, 2025, 8:54pm UTC](https://discourse.julialang.org/t/using-overlay-like-cassette-jl/124700/3 "2025-01-12T20:54:39Z")

</div>

It’s a way to get contextual dispatch and override dispatch rules for a specific scope. In a particular scope, the methods you define have higher priority than all existing ones.

`@overlay` is part of this and adds a method to a custom method table. It’s in `Base.Experimental` but I could never find proper documentation for it; I only learned how to use it from code searches: [Code search results · GitHub](https://github.com/search?q=language:julia+/@overlay/&type=code)

There are some docstrings available via help though:

> [@](#):
>
> ```julia
> Base.Experimental.@MethodTable name
> 
> ```
> 
> Create a new MethodTable in the current module, bound to name. This method table can be used with the Base.Experimental.@overlay macro to define methods for a function without adding them to the global method  
> table.
> 
> ```julia
> help?> Base.Experimental.@overlay
> 
> Base.Experimental.@overlay mt def
> 
> ```
> 
> Define a method and add it to the method table mt instead of to the global method table. This can be used to implement a method override mechanism. Regular compilation will not consider these methods, and you  
> should customize the compilation flow to look in these method tables (e.g., using Core.Compiler.OverlayMethodTable).
> 
> │ Note  
> │  
> │ Please be aware that when defining overlay methods using `@overlay`, it is not necessary to have an original method that corresponds exactly in terms of how the method dispatches. This means that the  
> │ method overlay mechanism enabled by `@overlay` is not implemented by replacing the methods themselves, but through an additional and prioritized method lookup during the method dispatch.  
> │  
> │ Considering this, it is important to understand that in compilations using an overlay method table like the following, the method dispatched by `callx(x)` is not the regular method `callx(::Float64)`, but  
> │ the overlay method `callx(x::Real)`:
> 
> ```julia
> │ callx(::Real) = :real
> │ @overlay SOME_OVERLAY_MT callx(::Real) = :overlay_real
> │ callx(::Float64) = :float64
> │
> │ # some overlay callsite
> │ let x::Float64
> │ callx(x) #> :overlay_real
> │ end
> 
> ```

I think the README of CassetteOverlay.jl is a useful example of how to use something like this. (Though I also [wish it had more docs](https://github.com/JuliaDebug/CassetteOverlay.jl/issues/59)!)
