# DifferentiationInterface do-block best practices

**URL:** <https://discourse.julialang.org/t/differentiationinterface-do-block-best-practices/131125>\
**Category:** Numerics\
**Tags:** question, autodiff\
**Created:** [July 28, 2025, 9:12am UTC](https://discourse.julialang.org/t/differentiationinterface-do-block-best-practices/131125 "2025-07-28T09:12:40Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![afleming](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/afleming/32/208443_2.png) [@afleming](https://discourse.julialang.org/u/afleming)\
**Post date:** [July 28, 2025, 9:12am UTC](https://discourse.julialang.org/t/differentiationinterface-do-block-best-practices/131125/1 "2025-07-28T09:12:40Z")

</div>

Is it better / recommended to use do-blocks that capture variables or should I use the Context mechanism provided by DifferentiationInterface?

Even though this

```julia
pack = (y0 = 1.0, y1 = 2.0)
x1 = [2.0, 4.0]
jac = DifferentiationInterface.jacobian(<some_backend>, x1) do x
  return (x[1] - pack.y0)^2 + (x[2]-pack.y1)^2
end

```

computes the same thing as this

```julia
pack = (y0 = 1.0, y1 = 2.0)
x1 = [2.0, 4.0]
jac = DifferentiationInterface.jacobian(<some_backend>, x1, Constant(pack.y0), Constant(pack.y1) do x, y0, y1
  return (x[1] - y0)^2 + (x[2]-y1)^2
end

```

is one preferable / better than the other? I suppose the second is much more amenable to use with the preparation mechanism.

---

<div class="post-metadata">

**Author:** ![gdalle](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gdalle/32/27854_2.png) [@gdalle](https://discourse.julialang.org/u/gdalle)\
**Post date:** [July 28, 2025, 3:15pm UTC](https://discourse.julialang.org/t/differentiationinterface-do-block-best-practices/131125/2 "2025-07-28T15:15:18Z")

</div>

Contexts are in general preferable because

- they allow stateless functions, which is an implicit assumption of many backends and makes code cleaner
- for some backends, captured variables would need to be tweaked to accommodate differentiation (eg `DI.Cache` with ForwardDiff.jl to work with dual numbers)
- for some backends, context annotations enable performance optimizations (eg `DI.Constant` with Enzyme.jl)
