Time-Marching Procedure in Tutorial Program

In the tutorial program, ‘Diffusion of a Gaussian function’ shown here https://jsdokken.com/dolfinx-tutorial/chapter2/diffusion_code.html,
an implicit Euler time discretization is used. The right-hand side vector in the variational formulation is then programmed as,

L = (u_n + dt * f) * v * ufl.dx
linear_form = fem.form(L)
b = create_vector(linear_form)

Then, to compute the solution at different time-steps, we have the following block of code

for i in range(num_steps):
    t += dt

    # Update the right hand side reusing the initial vector
    with b.localForm() as loc_b:
        loc_b.set(0)
    assemble_vector(b, linear_form)

Is the variable ‘linear_form’ somehow updated each time-step? If not, the implicit Euler scheme is not being used. To propagate the solution forward in time using implicit Euler, the solution at the previous time-step must be included in the right-hand-side vector of the discretized problem.

Am I missing something here?

It is updated because you are assigning data to u_n after solving:

 # Update solution at previous time step (u_n)
    u_n.x.array[:] = uh.x.array

and u_n is part of the linear form.
See for instance
Form compilation — FEniCS Tutorial @ Sorbonne for more information

I see, but the linear_form variable was defined prior to this, so I’m not sure how changing u_n automatically changes the linear form variable.

I know this probably sounds like a very basic question - I’m an applied mathematician and my only /formal/ training is in Matlab. So I’m not very well-versed on these things.

linear_form is a form object not just a variable, it stores the required informations for building the vector (for example linear_form and u are linked, or u is converted to a member variable of linear_form, I guess). Just take it as an useful blackbox.