the arguments of a function are passed by value or reference?

1,055 views
Skip to first unread message

yongchao ge

unread,
May 3, 2012, 10:50:35 AM5/3/12
to julia-dev
This is the first email for me to the julia list. I am an R programmer
who wants to utilize the fast speed of julia without working on C/C++
when the basic R is too slow and I have to write new algorithms.

Sorry for the newbie question as this seems the only email list for me
to ask questions. Is there a separate email list to ask stupid
questions for newbies?

My understanding is that in Julia for a function, the arguments are
passed by reference. I found that the behavior is inconsistent. See
the example below where in the swap function, a and b have not been
swapped at all, while in the changeone function, a[1] is actually
changed.

I guess the meaning of pass by reference is that if you change a part
of a argument variable, that change is visible after the exit of the
function (pass by reference), however, if you assign a new variable to
the argument variable, then the change is "not visible" after the exit
of the function (i.e. pass by value).

Best,

Yongchao

a=[1:4];b=[0:3]
swap=function(a,b)
c=a
a=b
b=c
end
swap(a,b)
a #a is still [1:4]

changeone=function(a,b)
a[1]=b
end
changeone(a,0)
a #a[1] is changed to 0

Keno Fischer

unread,
May 3, 2012, 11:05:54 AM5/3/12
to juli...@googlegroups.com
Yes, it's like passing a pointer. I don't know how familiar you're with C, but just in case consider the following C function.

void test(int *a, int *b) { //a and b are local variables pointing to the data at a and b
 *a = 0; //This changes the DATA at a (by dereferencing the pointer)
  a = b; //This changes the local variable a to point to the data at b, but it doesn't actually change the data that a used to point to.
}

Hope that makes sense.

yongchao ge

unread,
May 3, 2012, 11:47:15 AM5/3/12
to julia-dev
That clears up, Thanks Keno. I was thinking about the C++'s reference
(&) , not really thinking about passing the values of pointers. Is
this behavior documented somewhere?

Based on this understanding, I don't know how to rewrite the swap
function to make it work, though it was much easier in C with the
pointer (*) and address (&) or C++ with the reference (&). One idea I
can think about is by constructing tuples

swap=function(a,b)
c=a[1]
a[1]=b[1]
b[1]=c
end
swap((a,0),(b,0))

However, there is something wrong with a[1]=b[1]? I probably need to
delve more into Julia to understand how the tuple works. The tuple
behaves very differently than R or a struct of C pointers.


Yongchao

Stefan Karpinski

unread,
May 3, 2012, 11:54:52 AM5/3/12
to juli...@googlegroups.com
Swap can't be a function in any language because it changes the bindings in the calling scope. If something can do what you want swap to do, then it's necessarily more than just a function. In Julia you can do this as a macro:

macro swap(a,b)
    @gensym t
    :($t=$a; $a=$b; $b=$t)
end

julia> x = 1; y = "foo";

julia> @swap x y
1

julia> x
"foo"

julia> y
1

Then again, you can also just write this with parallel assignment instead:

julia> x = 1; y = "foo";

julia> x, y = y, x
("foo",1)

julia> x
"foo"

julia> y
1

Hope that helps a bit.

yongchao ge

unread,
May 3, 2012, 12:22:19 PM5/3/12
to julia-dev
Thanks Stefan for the macro (I need to understand the meaning of
gensym) and the elegant solution by x, y = y, x, which is quite simple
to use.

I may have objections in your statement that "Swap can't be a function
in any language because it changes the bindings in the calling scope"
unless the languages you referred do not include low level language
such as C or C++.

swap can be a function in C++ or the C as below (at least one
surface, I don't really know what's working behind the hood)

void swap1(int& a, int &b)
{
int c=b;
b=a;
a=c;
}
swap1(a,b);

or with a C function
void swap2(int *a, int *b)
{
int c=*b;
*b=*a;
*a=c;
}
swap2(&a,&b);

Jeff Bezanson

unread,
May 3, 2012, 12:31:53 PM5/3/12
to juli...@googlegroups.com
He means "function" here in the mathematical sense. In any case, our
functions can't manipulate bindings in other functions (unless they
are nested).

Stefan Karpinski

unread,
May 3, 2012, 12:55:54 PM5/3/12
to juli...@googlegroups.com
Right. In C you can manipulate the value of a variable through a pointer to it, which is actually pretty weird if you think about it. And it actually is very problematic for many kinds of optimizations. What if, for example, the compiler wanted to only store a and b in registers? Since you can't take the address of a register, it can't do that. Semantically, it has to write them to memory so that it can pass an address to the swap function through which it can change the value in memory. Of course, the compiler can still do something clever which avoids actually writing to memory, but it's a complication.
Reply all
Reply to author
Forward
0 new messages