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