# Difference between m = function(m) and function!(m) where m is a JuMP Model instance

**URL:** <https://discourse.julialang.org/t/difference-between-m-function-m-and-function-m-where-m-is-a-jump-model-instance/118831>\
**Category:** Optimization (Mathematical)\
**Tags:** jump\
**Created:** [August 31, 2024, 3:17am UTC](https://discourse.julialang.org/t/difference-between-m-function-m-and-function-m-where-m-is-a-jump-model-instance/118831 "2024-08-31T03:17:54Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![Betristor](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/betristor/32/45264_2.png) [@Betristor](https://discourse.julialang.org/u/Betristor)\
**Post date:** [August 31, 2024, 3:17am UTC](https://discourse.julialang.org/t/difference-between-m-function-m-and-function-m-where-m-is-a-jump-model-instance/118831/1 "2024-08-31T03:17:54Z")

</div>

I’ve read the performance tips about building models using juMP and it suggests to use exclamatory mark instead of return value. Is there any performance difference between these two ways in terms of memory usage?

---

<div class="post-metadata">

**Author:** ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)\
**Post date:** [August 31, 2024, 4:01am UTC](https://discourse.julialang.org/t/difference-between-m-function-m-and-function-m-where-m-is-a-jump-model-instance/118831/2 "2024-08-31T04:01:39Z")

</div>

> [@Betristor](#):
>
> performance tips about building models using juMP and it suggests to use exclamatory mark instead of return value

Where do we say this?

Note that `!` isn’t special in Julia. It’s just a letter. (Although some people use it to mean that an argument is mutated.)

So naming a function `foo!` instead of `foo` does not make a difference. I could have named it `foo_exclaimation` and it would be the same thing.

---

<div class="post-metadata">

**Author:** ![SteffenPL](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/steffenpl/32/206270_2.png) [@SteffenPL](https://discourse.julialang.org/u/SteffenPL)\
**Post date:** [August 31, 2024, 4:10am UTC](https://discourse.julialang.org/t/difference-between-m-function-m-and-function-m-where-m-is-a-jump-model-instance/118831/3 "2024-08-31T04:10:06Z")

</div>

A concrete example is maybe:

```julia
x = [1,2,3]

function square(x)
    return x .^ 2
end

function square!(x)
    @. x = x^2 
end

```

Look at the difference when calling

```julia
y = square(x)
println(x)
square!(x)
println(x)

```

the in-place version of a function should be marked with `!` to tell others that you change the inputs. (But as noted, it is just a convention in Julia.) The in-place version also uses less memory, as it can reuse the memory of `x`. That’s why it is sometimes relevant.

---

<div class="post-metadata">

**Author:** ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)\
**Post date:** [August 31, 2024, 4:20am UTC](https://discourse.julialang.org/t/difference-between-m-function-m-and-function-m-where-m-is-a-jump-model-instance/118831/4 "2024-08-31T04:20:57Z")

</div>

See also: [Style Guide](https://jump.dev/JuMP.jl/stable/developers/style/#Use-of-!)

For the most part, the JuMP codebase does not use `!`. For example, we have `set_lower_bound(x, value)` instead of `lower_bound!(x, value)`.

There is a valid question of: should I use a mutating function instead of one that returns a copy?

But that is a different question to the use of `!`.

---

<div class="post-metadata">

**Author:** ![Betristor](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/betristor/32/45264_2.png) [@Betristor](https://discourse.julialang.org/u/Betristor)\
**Post date:** [September 2, 2024, 1:35am UTC](https://discourse.julialang.org/t/difference-between-m-function-m-and-function-m-where-m-is-a-jump-model-instance/118831/5 "2024-09-02T01:35:38Z")

</div>

Taking my situation as an example, I created my JuMP model using return value with many functions, like

```julia
m = Model()
m = func1(m)
m = func2(m)
...
m = funcN(m)

```

Every function will take the model and modify it and return it. Will this consume more memory than the in-place version and is there an rough estimation about my memory overuse?

---

<div class="post-metadata">

**Author:** ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)\
**Post date:** [September 2, 2024, 1:52am UTC](https://discourse.julialang.org/t/difference-between-m-function-m-and-function-m-where-m-is-a-jump-model-instance/118831/6 "2024-09-02T01:52:22Z")

</div>

Provided you are not using `copy(m)` anywhere, there is no difference. They are exactly equivalent.

You can check that `m1 = func1(m)` and then `m1===m`.

---

<div class="post-metadata">

**Author:** ![Betristor](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/betristor/32/45264_2.png) [@Betristor](https://discourse.julialang.org/u/Betristor)\
**Post date:** [September 2, 2024, 2:35am UTC](https://discourse.julialang.org/t/difference-between-m-function-m-and-function-m-where-m-is-a-jump-model-instance/118831/7 "2024-09-02T02:35:04Z")

</div>

Thanks for the reply. I used to regard the return version will create a copy and take more memory consumption than the in-place version. Since I’m trying to reduce the massive memory consumption of my models, it seems my previous thinking was in a wrong direction.

---

<div class="post-metadata">

**Author:** ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)\
**Post date:** [September 2, 2024, 8:03am UTC](https://discourse.julialang.org/t/difference-between-m-function-m-and-function-m-where-m-is-a-jump-model-instance/118831/8 "2024-09-02T08:03:23Z")

</div>

> [@Betristor](#):
>
> I used to regard the return version will create a copy

This is not true for _any_ Julia code, regardless of JuMP. Julia does not pass by value.

The JuMP style guide does not recommend `!` specifically because new users think it is special, when it really is just another letter, like `a` or `Y`. And the the “modifies its argument” rule is a heuristic that is not applied uniformly.

---

<div class="post-metadata">

**Author:** ![yvikhlya](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yvikhlya/32/3753_2.png) [@yvikhlya](https://discourse.julialang.org/u/yvikhlya)\
**Post date:** [September 2, 2024, 12:39pm UTC](https://discourse.julialang.org/t/difference-between-m-function-m-and-function-m-where-m-is-a-jump-model-instance/118831/9 "2024-09-02T12:39:35Z")

</div>

> [@odow](#):
>
> Provided you are not using `copy(m)` anywhere, there is no difference. They are exactly equivalent.
> 
> You can check that `m1 = func1(m)` and then `m1===m`.

What is the message here?

```julia
f(x)=x.^2
a=rand(10)
b=f(a)
b===a
false
any(b.==a)
false

```

`a` and `b` are two different arrays with different elements. This is clearly different behavior than in-place modification.

---

<div class="post-metadata">

**Author:** ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)\
**Post date:** [September 2, 2024, 9:39pm UTC](https://discourse.julialang.org/t/difference-between-m-function-m-and-function-m-where-m-is-a-jump-model-instance/118831/10 "2024-09-02T21:39:35Z")

</div>

> This is clearly different behavior than in-place modification.

Yes. In your example, `f(x) = x.^2` returns a new vector. It does not do in-place modification.

In @Betristor’s example, they are using in-place modifications on a `JuMP.Model`. No function in JuMP makes a copy of the model without calling `copy(m)`. This is different to your `x.^2` example.

I was thinking of code like this:

```Julia
julia> function foo(x)
           x[1] = 2
           return x
       end
foo (generic function with 1 method)

julia> x = [1, 2, 3]
3-element Vector{Int64}:
 1
 2
 3

julia> y = foo(x)
3-element Vector{Int64}:
 2
 2
 3

julia> x
3-element Vector{Int64}:
 2
 2
 3

julia> x === y
true

```

My points were:

- In-place modification has nothing to do with whether the function has a `!` in its name.
- Just having `return x` does not make a copy of the return value.

The in-place version of your `f(x)` example is:

```Julia
julia> function foo_yvikhlya(x)
           x .^= 2
           return x
       end
foo_yvikhlya (generic function with 1 method)

julia> a = rand(10);

julia> b = foo_yvikhlya(a);

julia> b === a
true

julia> any(b .== a)
true

```

---

<div class="post-metadata">

**Author:** ![yvikhlya](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yvikhlya/32/3753_2.png) [@yvikhlya](https://discourse.julialang.org/u/yvikhlya)\
**Post date:** [September 2, 2024, 11:59pm UTC](https://discourse.julialang.org/t/difference-between-m-function-m-and-function-m-where-m-is-a-jump-model-instance/118831/11 "2024-09-02T23:59:04Z")

</div>

Oh ok, got it now. It was not clear from the discussion above that only mutating functions are meant. Indeed, for mutating function `x=f(x)` and `f(x)` are equivalent, although if the name does not have `!`, it may be confusing for users who got used to julia naming convention.
