# Mutable function parameter of primitive type

I’m going through Julia manual and I’m having a bit of a problem comprehending mutability and pass by sharing concept as applied to primitive types. Can some show me an example where `x` will be modified by calling `f(x)` so the value printed is not `42`:

``````x = 42
function f(x) ....... end
println(x)
``````

Let’s put aside the bigger question of sound software engineering practices. I just want to see it done. BTW, I know that wrapping `x` in a `mutable struct` would do the trick, but is this the only way?

No, primitive types like `Int` are immutable. You can only change their binding, not mutate their value.

As you alluded, the way to do this is wrapping in a mutable type, usually `Ref(x)` or whatever.

You can use the `isimmutable` function to see if a value may be mutated or not:

``````julia> isimmutable(42)
true
``````
1 Like

Note that rather than passing a number as a mutable parameter (e.g. wrapped in a `Ref`), it’s generally much better to simply return the updated value. You can return multiple values with a tuple.

3 Likes

Of course, but see my disclaimer about sound software engineering practices.

I would not contemplate to check `42` for immutability in my exercise, I would check `x`. When I do so, it doesn’t make much sense on the surface for someone coming from C++ world:

``````julia> x=0
0
julia> isimmutable(x)
true
julia> x=42
42
julia> x
42
``````

The difference is than in Julia, `x = 0` is just saying "bind the value `0` to the variable `x`". Then, when you later say `x = 42`, it’s again saying "bind the value 42 to the variable `x`".

No mutation is happening here, all that’s happening is that the value `x` is bound to is changing. This is unlike when you have `v = [1, 2, 3]` and you do `v[1] = 2` or something. That’s real mutation, not a changing of variable bindings.

1 Like

This requires a bit of a neural network rearrangement for an old C++ programmer. I will chew on it.

Yes, Julia is quite different from C++ in this respect.

In Julia, values can be immutable or mutable. The value 42 is immutable because it a primitive (immutable) type. The tuple `(1, 2)` is likewise immutable. A value of a `mutable struct` `x` is mutable because you can reach into it and modify it via `x.foo = 1`.

Variables in Julia are just labels. Doing `x = 0` attaches the label `x` to the value `0`. Doing `x = 42` attaches that label to a new value. It has no effect on the previous value that that label happened to be attached to.

This is completely different than C++. In C++, doing:

``````x = y
``````

can have arbitrary side-effects because it calls the `operator=` method of whatever the type of `x` is.

In Julia, doing `x = y` just attaches the label `x` to the value of `y`. It never has side-effects.

5 Likes

The first thing I tried after I got to `mutable struct` in the manual is:

``````julia> mutable y=0
ERROR: syntax: extra token "y" after end of expression
``````

There seems to be a bit of dichotomy between primitive and composite types in Julia, but I haven’t got to the end of the manual yet. Maybe it will become more clear later.

@pauljurczak maybe it helps to consider a similar example with a mutable value, for example an array?

``````x = [0,1]
y = x        # x and y both bound to the same value (a mutable array)
x[1] = 3     # change the array
y            # the change is also visible from the y binding
x = [5,6]    # x now bound to a new value: the array [5,6]
y            # y still bound to the first array: [3,1]
``````

So `x = ...` is indeed treated the same for mutable and immutable values. This syntax doesn’t change the value, instead it changes the meaning of `x`.

2 Likes

Right, this doesn’t mean anything in Julia because values are mutable, but variable names are just labels. You can always attach a label to a new value–there is no concept of mutability of the labels themselves.

3 Likes