I wander if the convention should have been made the other way as not all 
will know it at first..

If you do not want your arguments touched then you can trivially make a 
non-mutating wrapper using the similar function. It seems that could have 
been automated.. Maybe you can with a macro?

Would it be easy to give a warning or an error for functions that are 
mutating? Or really, if it can be detected then shouldn't the function be 
renamed to the ! variant and a wrapper be made?

Best regards,
Palli.

On Friday, December 26, 2014 8:42:18 PM UTC, Tomas Lycken wrote:
>
> Glad to be of service! =)
>
> Languages treat both aliasing and argument passing differently, so it 
> really just takes a little while to experiment and see how this language 
> plays out what you're trying to do. For what it's worth, Julia also has a 
> style convention to end all method names with a bang ("!") if they mutate 
> their arguments. So with your first example, the function could have been 
> named square!(arg), and then users of that function would be immediately 
> aware that arg would be changed. This convention isn't really enforced in 
> any way (except code review) - it's perfectly valid Julia to mutate 
> function arguments even if the function name doesn't end with ! - but the 
> core libraries as well as most packages do follow it.
>
> Happy coding!
>
> // Tomas
>
> On Friday, December 26, 2014 9:33:12 PM UTC+1, Bradley Setzler wrote:
>>
>> Thanks Tomas, the similar command will be very useful in avoiding this 
>> issue. 
>>
>> Thank you also for a thoughtful and informative response, Tomas.
>>
>> Bradley
>>
>> PS - For what it's worth, R does not have this behavior.
>>
>>
>>
>> On Friday, December 26, 2014 2:05:44 PM UTC-6, Tomas Lycken wrote:
>>>
>>> The main reason is performance; passing and aliasing arrays this way 
>>> (those are two different concepts, which work together to make this 
>>> particular example a little confusing) allow for writing code that is as 
>>> fast as possible, by leaving the coder in control of when a copy is made 
>>> and when it is not. A more idiomatic way of writing your square function, 
>>> which would do what you expect, would be
>>>
>>> ```
>>> function square(A)
>>>     A2 = similar(A)
>>>     for i = 1:length(A)
>>>         A2[i] = A[i]^2
>>>     end
>>>     A2
>>> end
>>> ```
>>>
>>> The funciton `similar` allocates new memory for an array of similar size 
>>> and type as `A`. You could also have left your entire method untouch except 
>>> setting `inner_var = copy(arg)`, but this would have meant both reading and 
>>> writing more to memory than you need to. As you see, Julia's behavior 
>>> allows you to write more performant code than what you'd do otherwise.
>>>
>>> // Tomas
>>>
>>> On Friday, December 26, 2014 8:58:04 PM UTC+1, Bradley Setzler wrote:
>>>>
>>>> Why would you want this behavior? How could you possibly benefit from 
>>>> modifying X anytime you modify Y just because Y=X initially? If I wanted 
>>>> to 
>>>> modify X, I would modify X itself, not Y. 
>>>>
>>>> Bradley
>>>>
>>>>
>>>>
>>>>
>>>> On Friday, December 26, 2014 1:53:12 PM UTC-6, John Myles White wrote:
>>>>>
>>>>> This is aliasing. Almost all languages allow this.
>>>>>
>>>>>  -- John
>>>>>
>>>>> Sent from my iPhone
>>>>>
>>>>> On Dec 26, 2014, at 2:49 PM, Bradley Setzler <[email protected]> 
>>>>> wrote:
>>>>>
>>>>> Hi,
>>>>>
>>>>> I cannot explain this behavior. I apply a function to a variable in 
>>>>> the workspace, the function initializes its local variable at the 
>>>>> workspace 
>>>>> variable, then modifies the local variable and produces the desired 
>>>>> output. 
>>>>> However, it turns out the Julia modifies both the local and workspace 
>>>>> variable with each operation on the local variable. Only the local 
>>>>> variable 
>>>>> is supposed to be modified. 
>>>>>
>>>>> *This is very dangerous behavior, as Julia is modifying the data 
>>>>> itself between performing operations on the data; the data itself is 
>>>>> supposed to remain fixed between operations on it.*
>>>>>
>>>>> *Minimal working example:*
>>>>>
>>>>> data=[1,2,3]
>>>>> function square(arg)
>>>>>     inner_var = arg
>>>>>     for i=1:length(inner_var)
>>>>>         inner_var[i] = inner_var[i]^2
>>>>>     end
>>>>>     return inner_var
>>>>> end
>>>>> output=square(data)
>>>>>
>>>>> julia> print(data)
>>>>>
>>>>> [1,4,9]
>>>>>
>>>>> The data has been squared due to the local variable, which was 
>>>>> initialized at the data values, being squared. Now, if i wish to apply a 
>>>>> different function to the data, the result will be incorrect because the 
>>>>> data has been modified unintentionally.
>>>>>
>>>>> How long has Julia been doing this? Was this behavior intentional?
>>>>> Bradley
>>>>>
>>>>>
>>>>>

Reply via email to