# \[ANN\] MutableArgumentContracts.jl (experimental, not yet registered)

**URL:** <https://discourse.julialang.org/t/ann-mutableargumentcontracts-jl-experimental-not-yet-registered/109488>\
**Category:** Package Announcements\
**Tags:** package, announcement\
**Created:** [January 31, 2024, 2:54am UTC](https://discourse.julialang.org/t/ann-mutableargumentcontracts-jl-experimental-not-yet-registered/109488 "2024-01-31T02:54:56Z")\
**Posts on this page:** 4\
**Page:** 2

<div class="post-metadata">

**Author:** ![BioTurboNick](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bioturbonick/32/6380_2.png) [@BioTurboNick](https://discourse.julialang.org/u/BioTurboNick)\
**Post date:** [February 1, 2024, 7:42pm UTC](https://discourse.julialang.org/t/ann-mutableargumentcontracts-jl-experimental-not-yet-registered/109488/21 "2024-02-01T19:42:32Z")

</div>

Good question, I wanted to avoid any confusion with the `!` negation operator. Even though it’s not an issue on the function definition side. Also the convention for mutable function is for it to appear after the name. In a speculative 2.0, Julia could potentially formalize `!` as a suffix that perhaps invoked similar functionality, without the extra syntax overhead, e.g. `foo!(x!, y!::DenseVector, z)`

---

<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:** [February 1, 2024, 8:18pm UTC](https://discourse.julialang.org/t/ann-mutableargumentcontracts-jl-experimental-not-yet-registered/109488/22 "2024-02-01T20:18:28Z")

</div>

I think that should work for dispatch because subtyping of type parameter constraints implies subtyping of the iterated unions. For example, `AbstractVector` is a supertype of both `Vector` and `UnitRange`, and `X{S} where S<:AbstractVector` is a supertype of both `X{Vector}` and `X{UnitRange}`. This isn’t exactly parameter covariance, as the type constraints are not the parameters, and `TypeVar` parameters like `S` are not types let alone subtypes. Involving iterated unions and type constraints do complicate things, but I don’t think that’ll be much of an issue. The 2-tuple idea and the iterated union idea add about the same extra hurdles to get to the important type e.g. `Tuple{Ref, Integer}.parameters[2]` versus `Ref{<:Integer}.var.ub` to get to `Integer`.

> [@adienes](#):
>
> well, I guess technically the `rng` is mutated, but that’s not really what the `!` is getting at I think

The exception for mutations of obvious and possibly default arguments is documented [here](https://docs.julialang.org/en/v1/manual/style-guide/#bang-convention):

> Functions related to IO or making use of random number generators (RNG) are notable exceptions: Since these functions almost invariably must mutate the IO or RNG, functions ending with `!` are used to signify a mutation _other_ than mutating the IO or advancing the RNG state. For example, `rand(x)` mutates the RNG, whereas `rand!(x)` mutates both the RNG and `x` ; similarly, `read(io)` mutates `io` , whereas `read!(io, x)` mutates both arguments.

> [@BioTurboNick](#):
>
> In a speculative 2.0, Julia could potentially formalize `!` as a suffix

My personal notation is to keep `!` for callables that mutate inputs and suffix the variables for said inputs with `!!`. I don’t really use this much because the existing convention and descriptive names are almost always good enough, I’ve done this when I really need the variable to stick out to me.

---

<div class="post-metadata">

**Author:** ![Palli](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/palli/32/3380_2.png) [@Palli](https://discourse.julialang.org/u/Palli)\
**Post date:** [February 1, 2024, 9:37pm UTC](https://discourse.julialang.org/t/ann-mutableargumentcontracts-jl-experimental-not-yet-registered/109488/23 "2024-02-01T21:37:34Z")

</div>

> [@BioTurboNick](#):
>
> As long as we have to worry about slow heap allocations, we will need to worry about mutating functions, I think.

You can use Bumper.jl for the cases I think you have in mind. [and heap allocations aren’t actually slow, they are rather fast, just imply GC pressure, but the optimizer could free in many cases like Mojo, automatically, what Bumper does manually.]

---

<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:** [February 1, 2024, 11:45pm UTC](https://discourse.julialang.org/t/ann-mutableargumentcontracts-jl-experimental-not-yet-registered/109488/24 "2024-02-01T23:45:52Z")

</div>

> [@Palli](#):
>
> heap allocations aren’t actually slow, they are rather fast, just imply GC pressure

Even if we discount the time taken taken by the GC, typical heap allocations do take more and poorly bounded time to find large enough blocks of free memory, compared to stack allocations. Heap allocations can get much faster when limitations on how you allocate can be communicated, like with Bumper.jl.

[Previous page](https://discourse.julialang.org/t/ann-mutableargumentcontracts-jl-experimental-not-yet-registered/109488.md?page=1)
