Pass by reference

532 views
Skip to first unread message

David Higgins

unread,
Feb 17, 2015, 10:54:37 AM2/17/15
to julia...@googlegroups.com

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.


Stefan Karpinski

unread,
Feb 17, 2015, 11:41:45 AM2/17/15
to Julia Users

David Higgins

unread,
Feb 17, 2015, 11:59:19 AM2/17/15
to julia...@googlegroups.com
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:

Jiahao Chen

unread,
Feb 17, 2015, 12:19:45 PM2/17/15
to julia...@googlegroups.com
Please DO open a pull request with suggested edits to the documentation!

Thanks,

Jiahao Chen
Staff Research Scientist
MIT Computer Science and Artificial Intelligence Laboratory

Stefan Karpinski

unread,
Feb 17, 2015, 12:41:35 PM2/17/15
to Julia Users
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. 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.

David Higgins

unread,
Feb 25, 2015, 8:26:04 AM2/25/15
to julia...@googlegroups.com
Thanks Stefan! That really helps.

I don't know if you guys have such a thing as a language specification document (I'm guessing the language is too much in evolution at present for that to be the case), but if you do I'd be happy to work towards porting bits of it to the main documentation.

David.


On Tuesday, 17 February 2015 18:41:35 UTC+1, Stefan Karpinski wrote:
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 - private. 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 <daithio...@gmail.com> 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:
Reply all
Reply to author
Forward
0 new messages