A mutable object can have its fields changed after creation. In Julia, a composite type defined with `struct` is immutable by default. Add `mutable` when operations need to update an instance’s fields, such as an archer spending arrows or a rocket changing its active stage. Immutability can help avoid bugs, so make mutability an explicit choice. section 7.3.2 section 7.5
Spend an arrow
```julia mutable struct Archer arrows::Int end function shoot!(archer::Archer) if archer.arrows > 0 archer.arrows -= 1 end archer end julia> robin = Archer(24) Archer(24) julia> shoot!(robin) Archer(23) ``` The `!` signals a mutating function by convention; it does not make mutation happen. Returning the changed object makes the result easy to inspect in the REPL. section 7.3.2
Mutability also supports collection-like operations. A staged rocket can update its `nextstage` field, while a space vehicle updates `activestage` as stages are added or removed with `pushfirst!` and `popfirst!`. These operations need mutable structs because they reassign fields. Changing a type definition itself is different from changing an instance: after making an existing struct mutable, restart the Julia REPL because types cannot be modified at runtime. section 12.6.1
Listing 12.28 Removing stages from the bottom
import Base: popfirst!, pushfirst!
tail(r::StagedRocket) = r.nextstage
tail(r::Rocket) = nothing
function popfirst!(ship::SpaceVehicle)
r = tail(ship.activestage)
if r == nothing #1
throw(throw(ArgumentError
("no rocket stages left"))) #2
else
discarded = ship.activestage #3
discarded.nextstage = emptypayload #4
ship.activestage = r #5
end
discarded #6
end
Follow `popfirst!` as it detaches the current stage, changes the vehicle’s active-stage field, and returns the discarded stage. section 12.6.1



