12

In julia how do we know if a type is manipulated by value or by reference?

In java for example (at least for the sdk):

  • the basic types (those that have names starting with lower case letters, like "int") are manipulated by value

  • Objects (those that have names starting with capital letters, like "HashMap") and arrays are manipulated by reference

It is therefore easy to know what happens to a type modified inside a function.

I am pretty sure my question is a duplicate but I can't find the dup...

EDIT

This code :

function modifyArray(a::Array{ASCIIString,1})
    push!(a, "chocolate")
end

function modifyInt(i::Int)
    i += 7
end

myarray = ["alice", "bob"]
modifyArray(myarray)
@show myarray

myint = 1
modifyInt(myint)
@show myint

returns :

myarray = ASCIIString["alice","bob", "chocolate"]
myint = 1

which was a bit confusing to me, and the reason why I submitted this question. The comment of @StefanKarpinski clarified the issue.

My confusion came from the fact i considred += as an operator , a method like push! which is modifying the object itself . but it is not.

i += 7 should be seen as i = i + 7 ( a binding to a different object ). Indeed this behavior will be the same for modifyArray if I use for example a = ["chocolate"].

Issam T.
  • 1,677
  • 1
  • 14
  • 32

2 Answers2

16

The corresponding terms in Julia are mutable and immutable types:

  • immutable objects (either bitstypes, such as Int or composite types declared with immutable, such as Complex) cannot be modified once created, and so are passed by copying.

  • mutable objects (arrays, or composite types declared with type) are passed by reference, so can be modified by calling functions. By convention such functions end with an exclamation mark (e.g., sort!), but this is not enforced by the language.

Note however that an immutable object can contain a mutable object, which can still be modified by a function.

This is explained in more detail in the FAQ.

Charles
  • 947
  • 1
  • 15
  • 39
Simon Byrne
  • 7,694
  • 1
  • 26
  • 50
  • 3
    The key fact, however, is that all values are manipulated by reference. – StefanKarpinski Aug 13 '16 at 22:19
  • 4
    See also: http://stackoverflow.com/questions/33002572/creating-copies-in-julia-with-operator, http://stackoverflow.com/questions/35235597/julia-function-argument-by-reference. – StefanKarpinski Aug 13 '16 at 22:32
  • @StefanKarpinski Thanks, it is clear. I had just confused myself ... I've edited my question in case someone else falls in the same trap – Issam T. Aug 14 '16 at 00:04
  • Just pointing out the statement "immutable objects [...] are passed by copying" is only true for `isbits` types. e.g. `a = "hello"; f(x) = pointer(x); pointer(a) == f(a) #true, passed by reference`. It's just that they're immutable, so you can't really do much to them inside a function. But you *could* alter it via unsafe_pointers etc if you really wanted to, so the distinction matters. – Tasos Papastylianou Aug 14 '16 at 21:02
  • 1
    Also, that certain immutable objects are passed by copying is an implementation detail. From the user's perspective, all arguments are passed by sharing. – Fengyang Wang Aug 15 '16 at 04:35
3

I think the most rigourous answer is the one in

Julia function argument by reference

Strictly speaking, Julia is not "call-by-reference" but "call-by-value where the value is a reference" , or "call-by-sharing", as used by most languages such as python, java, ruby...

Community
  • 1
  • 1
Issam T.
  • 1,677
  • 1
  • 14
  • 32