Hi Spencer, Thanks for trying to explain the behavior. I can see how that might make sense to a computer scientist. However, I think most scientists would agree that having the behavior of = depends on whether the right hand side is an array or an expression is counter intuitive.
In any case, I spent a good while searching and couldn't find anywhere in the documentation that states what "=" does x = w results in copying a pointer to the location of the w array, rather than constructing a new array. Cheers, Eric On Saturday, January 25, 2014 12:26:37 AM UTC-5, Spencer Russell wrote: > > 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]<javascript:> > > 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] <javascript:>> >> 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) >>>>>> >>>>>> >>>>> >> >
