The confusion stems from this: *assignment and mutation are not the same
thing.*

*Assignment. *Assignment looks like `x = ...` – what's left of the `=` is a
variable name.

Assignment changes which object the variable `x` refers to (this is called
a variable binding). It doesn't mutate any objects at all.

*Mutation.* There are two typical ways to mutate something in Julia:

   - `x.f = ...` – what's left of the `=` is a field access expression;
   - `x[i] = ...` – what's left of the `=` is an indexing expression.

Currently, field mutation is fundamental – that syntax can *only* mean that
you are mutating a structure by changing its field. This may change
<https://github.com/JuliaLang/julia/issues/1974>. Array mutation syntax is
not fundamental – `x[i] = y` means `setindex!(x, y, i)` and you can either
add methods to setindex! or locally change which generic function
`setindex!`. Actual array assignment is a builtin – a function implemented
in C (and for which we know how to generate corresponding LLVM code).

Mutation changes the values of objects; it doesn't change any variable
bindings. After doing either of the above, the variable `x` still refers to
the same object it did before; that object may have different contents,
however. In particular, if that object is accessible from some other scope
– say the function that called one doing the mutation – then the changed
value will be visible there. But no bindings have changed – all bindings in
all scopes still refer to the same objects.

You'll note that in this explanation I never once talked about mutability
or immutability. That's because it has nothing to do with any of this –
mutable and immutable objects have exactly the same semantics when it comes
to assignment, argument passing, etc. The only difference is that if you
try to do `x.f = ...` when x is immutable, you will get a runtime error.

Maybe we should put this explanation in the manual somewhere. If someone
wants to make a pull request doing that, you can use any of my text here.

On Tue, Feb 17, 2015 at 11:59 AM, David Higgins <[email protected]>
wrote:

> Thanks Stefan,
>
> I did actually see these. I was partly raising this as a didactic point as
> the discussion group site is searchable. I think that my main suggestion
> would be that a section on which types are Mutable and which types are
> Immutable be added to the Types documentation page (and that a relevant
> comment also be added to the pages "Variables", "Integers and
> Floating-point numbers", etc.) While I occasionally find passing comment to
> specific types being mutable (eg. arrays), I haven't yet found a tableau of
> different types and their mutability status nor a statement that "when in
> doubt assume it's immutable" (which would probably be a dangerous
> assumption, right?).
>
> I don't know how you feel about it, but I figure that raising issues like
> this on the discussion forum allows for the documentation to evolve to a
> state where there are a lot less newbie questions eventually.
>
> David.
>
> On Tuesday, 17 February 2015 17:41:45 UTC+1, Stefan Karpinski wrote:
>>
>> See:
>>
>> http://julia.readthedocs.org/en/latest/manual/faq/#i-
>> passed-an-argument-x-to-a-function-modified-it-inside-
>> that-function-but-on-the-outside-the-variable-x-is-still-unchanged-why -
>> private
>> <http://julia.readthedocs.org/en/latest/manual/faq/#i-passed-an-argument-x-to-a-function-modified-it-inside-that-function-but-on-the-outside-the-variable-x-is-still-unchanged-why>
>>
>> http://julia.readthedocs.org/en/latest/manual/faq/#why-
>> does-x-y-allocate-memory-when-x-and-y-are-arrays - private
>> <http://julia.readthedocs.org/en/latest/manual/faq/#why-does-x-y-allocate-memory-when-x-and-y-are-arrays>
>>
>>
>> On Tue, Feb 17, 2015 at 10:54 AM, David Higgins <[email protected]>
>> wrote:
>>
>>>
>>> In Julia, all arguments to functions are passed by reference.
>>>
>>>
>>> Is this really true? I know it's written in the multi-dimensional arrays
>>> section of the manual but it's a pretty broad statement. I was trying to
>>> debug some code, the issue turns out to have nothing to do with how values
>>> are passed to functions, but I got a bit frustrated by the following
>>> behaviour.
>>>
>>> This one works
>>> type TType
>>>   val :: Int;
>>> end
>>>
>>> function boo(tt :: TType)
>>>   tt.val = 7
>>> end
>>>
>>> t = TType(20)
>>> t.val
>>> boo(t)
>>> t.val
>>>
>>> This one doesn't
>>> function hoo(d :: Int)
>>>      d += 1;
>>> end
>>>
>>> a = 2
>>> hoo(a)
>>> a
>>>
>>>
>>> Now let's go crazy:
>>> function goo(s)
>>>            s += 1;
>>> end
>>>
>>> function zoo(w)
>>>            w[1] += 1;
>>>            w[2] -= 1;
>>> end
>>>
>>> d = [1 2]
>>> goo(d)
>>> d
>>> zoo(d)
>>> d
>>>
>>> Part of me 'gets it'. But on another level I find this a little
>>> inconsistent (I have similar issues with some of the variable scoping
>>> rules). I'm not necessarily opposed to the choices which have been made but
>>> I find that they're not really expanded upon in the manual in sufficient
>>> detail.
>>>
>>> Have I missed something? (I'm looking for pointers to make my life
>>> easier, I'm not here to whinge about the frankly sterling work the
>>> developers are doing).
>>>
>>> Thanks,
>>> David.
>>>
>>>
>>>
>>

Reply via email to