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. >>> >>> >>> >>
