In f1, w += 10.0 expands to w = w + 10.0. So this creates a new array with
the value of (w + 10.0) and assigns that array to the name w. It could just
as easily been x = w + 10, in which case x and w would be separate arrays.

in f2, no new array creation takes place, you're just assigning w to point
to the same array that x points to, then you start mutating values.

So in the statements `w = x` and `w = x + 10`, the equals sign is doing the
same thing, it's just that in the latter case the + method is creating a
new array.

You can see the same behavior with:

a = [1:10]
b = a
a === b # true, because a and b are just different names for the same array
b += 1
a === b # false, because now b is a different array.

I can see how this could be a little confusing, as one might expect (+=) to
be an in-place operation. In fact though, the behavior  of x += y is
consistent with x = x + y, which is consistent with z = x + y.

-s


On Sat, Jan 25, 2014 at 12:07 AM, John Myles White <[email protected]
> wrote:

> Hi Eric,
>
> I think you’re being confused by the distinction between the bindings of
> variables and values, which can be bound to variables.
>
> If w is an Array, then an expression like
>
> w = [1, 2, 3]
>
> assigns a value (namely the value of an array containing 1, 2 and 3) to
> the variable w.
>
> In contrast, an expression like
>
> w[1] = 4
>
> does not refer to a variable called w[1]. It refers to a position in
> memory whose value is being mutated to 4.
>
>  — John
>
> On Jan 24, 2014, at 9:01 PM, Eric Ford <[email protected]> wrote:
>
> Hi Ivar,
>
> Thanks for the idea.  But replacing w += 10 with w = w + 10 still gives
> the same problem.   (As does w = w .+ 10).
> Either way, after calling f2, the values of x are modified.
>
> Even stranger, the values of x are not modified by the following function
> function f3(x::Array)
>  w = x + 0.
>  for i in 1:length(w)
>    w[i] = w[i] + 10.0
>  end
>  return w
> end
> So the behavior of future lines of code depends on whether w is
> initialized as w = x or w = x + 0.
>
> It appears that for some reason, julia is doing different things when the
> right hand side is just an array, versus when it is an expression.
> Maybe somebody considers that a feature, but it's definitely
> non-intuitive.
>
> I can't find any mention of this in the documentation.  Amusingly, there
> appears to be basically no documentation for what "=" does (despite it
> being the most common symbol in most every julia program).
> I thought = might be implemented as a generic function with different
> behaviors for Arrays and expressions, but methods(=) and help(=) turned up
> nothing.
> On one hand, it seems, like = should be fairly obvious, but evidently
> there are currently important differences in the behavior of = that need to
> be documented and/or corrected.
>
> Cheers,
> Eric
>
>
> On Friday, January 24, 2014 2:38:53 PM UTC-5, Ivar Nesje wrote:
>>
>> It becomes more obvious if you write "a += 3" as the longer form "a = a +
>> 4"
>>
>> kl. 19:57:22 UTC+1 fredag 24. januar 2014 skrev Eric Ford følgende:
>>>
>>> Sorry.  (Evidently, downloading a notebook is based on the last saved
>>> version and what's currently on your screen.)  IJulia notebook attached.
>>>  Readable version below.
>>>
>>> function f1(x::Array)
>>>  w = x
>>>  w += 10.0
>>>  return w
>>> end
>>>
>>> function f2(x::Array)
>>>  w = x
>>>  for i in 1:length(x)
>>>    w[i] += 10.0
>>>  end
>>>  return w
>>> end
>>>
>>> x=randn(10)
>>> x_orig = deepcopy(x)
>>> f1_of_x = f1(x)
>>> println("After f1: ",sum((x.-x_orig).^2));
>>> x = deepcopy(x_orig)
>>> f2_of_x = f2(x)
>>> println("After f2: ",sum((x.-x_orig).^2));
>>>
>>> After f1: 0.0
>>> After f2: 1000.0
>>>
>>>
>>> Thanks,
>>> Eric
>>>
>>>
>>>
>>> On Friday, January 24, 2014 1:10:59 PM UTC-5, Kevin Squire wrote:
>>>>
>>>> In what you posted,  `f1` and `f2` are identical (except for the
>>>> name).  Can you share the output of a Julia or IJulia session showing the
>>>> problem?
>>>>
>>>> Cheers,
>>>>    Kevin
>>>>
>>>>
>>>> On Fri, Jan 24, 2014 at 9:58 AM, Eric Ford <[email protected]> wrote:
>>>>
>>>>> I don't understand why the first function doesn't change x, but the
>>>>> second function does.
>>>>> Is the = calling deepcopy in f1, but copy in f2?
>>>>> If so, why?
>>>>>
>>>>> function f1(x::Array)
>>>>>  w = x
>>>>>  for i in 1:length(x)
>>>>>    w[i] += 10.0
>>>>>  end
>>>>>  w += 10.0
>>>>>  return w
>>>>> end
>>>>>
>>>>> function f2(x::Array)
>>>>>  w = x
>>>>>  for i in 1:length(x)
>>>>>    w[i] += 10.0
>>>>>  end
>>>>>  w += 10.0
>>>>>  return w
>>>>> end
>>>>>
>>>>> x=randn(10)
>>>>> x_orig = deepcopy(x)
>>>>> f_of_x = f(x)
>>>>> sum((x.-x_orig).^2)
>>>>>
>>>>> After f1: 0.0
>>>>> After f2: 1000.0
>>>>>
>>>>> Thanks,
>>>>> Eric (on behalf of an Astro 585 student)
>>>>>
>>>>>
>>>>
>

Reply via email to