# Callback in DifferentialEquation.jl changes the \`p\` parameter vector. Is this expected behaviour?

**URL:** https://discourse.julialang.org/t/callback-in-differentialequation-jl-changes-the-p-parameter-vector-is-this-expected-behaviour/131273
**Category:** Modelling & Simulations
**Created:** [August 1, 2025, 9:32am UTC](https://discourse.julialang.org/t/callback-in-differentialequation-jl-changes-the-p-parameter-vector-is-this-expected-behaviour/131273 "2025-08-01T09:32:15Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![Vitor\_Patricio\_Canta](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vitor_patricio_canta/32/50861_2.png) [@Vitor\_Patricio\_Canta](https://discourse.julialang.org/u/Vitor_Patricio_Canta)
#### Post date: [August 1, 2025, 9:32am UTC](https://discourse.julialang.org/t/callback-in-differentialequation-jl-changes-the-p-parameter-vector-is-this-expected-behaviour/131273/1 "2025-08-01T09:32:15Z")

</div>

This is a MWE showing that `p` defined outside of the integrator is also modified by the callback.  
Is this expected behaviour?

Thanks,

```julia-auto
using OrdinaryDiffEq
function rhs(du, u, p, t)
    V, Q, c_in = p
    c = u[1]
    du[1] = (Q/V) * (c_in - c)
end
tspan = (0.0, 10000.0) # Time span for the simulation
u0 = [0.0] # Initial concentrations
c_in = 2e-3 # Inlet concentration
V = 0.1 # Volume of the reactor
Q = 2e-3 # Flow rate in l/s
p = [V, Q, c_in]
@show p
condition(u, t, integrator) = t == 5000.0
affect!(integrator) = integrator.p[3] = 0.0 # Set c_in to 0 at t = 5000s
cb = DiscreteCallback(condition, affect!)
prob = ODEProblem(rhs, u0, tspan, p)
sol = solve(prob, Tsit5(), abstol=1e-8, reltol=1e-8,
 callback=cb, tstops = [5000.0])
@show p

```

---

<div class="post-metadata">

### Author: ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)
#### Post date: [August 1, 2025, 1:13pm UTC](https://discourse.julialang.org/t/callback-in-differentialequation-jl-changes-the-p-parameter-vector-is-this-expected-behaviour/131273/2 "2025-08-01T13:13:23Z")

</div>

Yes it’s expected. A variable does not store an object (unlike some other languages), it’s just a name that can be associated with 1 object at a time. The change you can directly make to a variable is that association, in other words reassigning it. On the other hand, 1 object can be associated with many names or other kinds of references, and a change to an object is mutation.

You never reassign the global `p`, so it’s always associated with the same vector. You mutated that vector from another reference `integrator.p`, so when you go to print the object associated with `p`, you get that mutated vector.

Note that `c_in` wasn’t reassigned either, so making another vector `[V, Q, c_in]` contains the original values. Generally when you pass variables into function calls (or expressions like array literals that lower to function calls), the associated objects are inputted, not the variables themselves. In the case of that vector, its elements are assigned to the same objects as the written variables’. Inputting variables somewhat occurs with variable capture by closures (methods in local scopes, comprehensions).

---

<div class="post-metadata">

### Author: ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)
#### Post date: [August 1, 2025, 1:40pm UTC](https://discourse.julialang.org/t/callback-in-differentialequation-jl-changes-the-p-parameter-vector-is-this-expected-behaviour/131273/3 "2025-08-01T13:40:01Z")

</div>

In the alias controls you can choose for p to not be aliased

---

<div class="post-metadata">

### Author: ![Vitor\_Patricio\_Canta](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vitor_patricio_canta/32/50861_2.png) [@Vitor\_Patricio\_Canta](https://discourse.julialang.org/u/Vitor_Patricio_Canta)
#### Post date: [August 2, 2025, 9:33am UTC](https://discourse.julialang.org/t/callback-in-differentialequation-jl-changes-the-p-parameter-vector-is-this-expected-behaviour/131273/4 "2025-08-02T09:33:06Z")

</div>

Thank you for the replies Benny and Chris!  
I should have expected that the default behaviour should be to mutate `p`, but it can be harder to track when we first pass it to a problem and it goes and gets mutated in this integrator object, inside a callback in the solve step.  
I am glad I can control this aliasing. This below works:

```julia-auto
using OrdinaryDiffEq
using Plots
function rhs(du, u, p, t)
    V, Q, c_in = p
    c = u[1]
    du[1] = (Q/V) * (c_in - c)
end
tspan = (0.0, 10000.0) # Time span for the simulation
u0 = [0.0] # Initial concentrations
c_in = 2e-3 # Inlet concentration
V = 0.1 # Volume of the reactor
Q = 2e-3 # Flow rate in l/s
p = [V, Q, c_in]
@show p
condition(u, t, integrator) = t == 5000.0
affect!(integrator) = integrator.p[3] = 0.0 # Set c_in to 0 at t = 5000s
cb = DiscreteCallback(condition, affect!)

alias = ODEAliasSpecifier(alias_p = false)
prob = ODEProblem(rhs, u0, tspan, p)
sol = solve(prob, Tsit5(), abstol=1e-8, reltol=1e-8,
           callback=cb, tstops = [5000.0], alias = alias)

@show p # Original p should be unchanged
fig = plot(sol, xlabel="Time (s)", ylabel="Concentration (mol/l)", title="CSTR Concentration Dynamics")
display(fig)

```
