January 30, 2014 Re: Array as an argument, ambiguous behaviour. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Cooler | On Thursday, 30 January 2014 at 15:59:48 UTC, Cooler wrote:
> On Thursday, 30 January 2014 at 15:51:44 UTC, Tobias Pankrath wrote:
>> On Thursday, 30 January 2014 at 15:49:35 UTC, Cooler wrote:
>>>>> I agree. I just want that the case can be expressed in language syntax more obvious - something like "fun(int[] const x){}" to emphasize that I understand that fun() can change content of array, and cannot change the {pointer,size} pair.
>>>>
>>>> That's what fun(int[] x) does :)
>>>>
>>>> -Steve
>>>
>>> Again...
>>> void fun(int[] x){ x ~= 5; }
>>> auto a = new int[10];
>>> fun(a); // Can you predict the content of 'a'?
>>
>>
>> It's [0, 0, 0, 0, 0, 0, 0, 0, 0, 0].
>
> No!!! It depends how runtime allocates memory for the array. Read http://dlang.org/d-array-article.html.
> If 'a' has internal space enough to place '5' the caller will see
> [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5].
Sorry!!! My mistake. The caller will see [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] :)
|
January 30, 2014 Re: Array as an argument, ambiguous behaviour. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Cooler | On Thursday, 30 January 2014 at 16:01:32 UTC, Cooler wrote:
> On Thursday, 30 January 2014 at 15:59:48 UTC, Cooler wrote:
>> On Thursday, 30 January 2014 at 15:51:44 UTC, Tobias Pankrath wrote:
>>> On Thursday, 30 January 2014 at 15:49:35 UTC, Cooler wrote:
>>>>>> I agree. I just want that the case can be expressed in language syntax more obvious - something like "fun(int[] const x){}" to emphasize that I understand that fun() can change content of array, and cannot change the {pointer,size} pair.
>>>>>
>>>>> That's what fun(int[] x) does :)
>>>>>
>>>>> -Steve
>>>>
>>>> Again...
>>>> void fun(int[] x){ x ~= 5; }
>>>> auto a = new int[10];
>>>> fun(a); // Can you predict the content of 'a'?
>>>
>>>
>>> It's [0, 0, 0, 0, 0, 0, 0, 0, 0, 0].
>>
>> No!!! It depends how runtime allocates memory for the array. Read http://dlang.org/d-array-article.html.
>> If 'a' has internal space enough to place '5' the caller will see
>> [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5].
>
> Sorry!!! My mistake. The caller will see [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] :)
But that is the proof. The intention of fun() implementer will not be achieved. And such misunderstanding will appear only at runtime.
|
January 30, 2014 Re: Array as an argument, ambiguous behaviour. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Cooler | On Thu, 30 Jan 2014 10:49:34 -0500, Cooler <kulkin@hotbox.ru> wrote: > On Thursday, 30 January 2014 at 15:29:50 UTC, Steven Schveighoffer wrote: >> On Thu, 30 Jan 2014 10:24:14 -0500, Cooler <kulkin@hotbox.ru> wrote: >> >>> On Thursday, 30 January 2014 at 14:40:36 UTC, Dicebot wrote: >>> I agree. I just want that the case can be expressed in language syntax more obvious - something like "fun(int[] const x){}" to emphasize that I understand that fun() can change content of array, and cannot change the {pointer,size} pair. >> >> That's what fun(int[] x) does :) >> >> -Steve > > Again... > void fun(int[] x){ x ~= 5; } > auto a = new int[10]; > fun(a); // Can you predict the content of 'a'? I suspect you mean: void fun(int[] x) {x.length += 1; x[0] = 5;} I cannot predict what the caller will see. But this is not a problem of *signatures*. The caller will not see ANY changes to {pointer,size} pair of x. That is the point -- it's passed by value. Note that this implementation is completely predictable: void fun(int[] x) {x[0] = 5; x.length += 1;} I want to stress that just because you can find an implementation that has a bug doesn't mean that there is an opportunity for the compiler to detect that bug, especially a logic bug. The compiler simply cannot know what you are thinking. > In your case: > void fun(int[] x){ x = [1, 2]; } // Compilation ok. Implementation's error. > The fun() implementer made error and think that caller will get new array. But it will get it only at runtime! > If we for example (just for example) have > void fun(int[] const x){ x = [1, 2]; } // Compilation error. I see very little value in that. We don't need to obliterate a tremendous amount of slice usage (not mentioning how much code will have to be updated) in order to help newbies understand how slices work. -Steve |
January 30, 2014 Re: Array as an argument, ambiguous behaviour. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Cooler | On Thu, 30 Jan 2014 11:04:44 -0500, Cooler <kulkin@hotbox.ru> wrote:
> On Thursday, 30 January 2014 at 16:01:32 UTC, Cooler wrote:
>> On Thursday, 30 January 2014 at 15:59:48 UTC, Cooler wrote:
>>> On Thursday, 30 January 2014 at 15:51:44 UTC, Tobias Pankrath wrote:
>>>> On Thursday, 30 January 2014 at 15:49:35 UTC, Cooler wrote:
>>>>>>> I agree. I just want that the case can be expressed in language syntax more obvious - something like "fun(int[] const x){}" to emphasize that I understand that fun() can change content of array, and cannot change the {pointer,size} pair.
>>>>>>
>>>>>> That's what fun(int[] x) does :)
>>>>>>
>>>>>> -Steve
>>>>>
>>>>> Again...
>>>>> void fun(int[] x){ x ~= 5; }
>>>>> auto a = new int[10];
>>>>> fun(a); // Can you predict the content of 'a'?
>>>>
>>>>
>>>> It's [0, 0, 0, 0, 0, 0, 0, 0, 0, 0].
>>>
>>> No!!! It depends how runtime allocates memory for the array. Read http://dlang.org/d-array-article.html.
>>> If 'a' has internal space enough to place '5' the caller will see
>>> [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5].
>>
>> Sorry!!! My mistake. The caller will see [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] :)
>
> But that is the proof. The intention of fun() implementer will not be achieved. And such misunderstanding will appear only at runtime.
void foo(int x)
{
x = 5;
}
"hey, why doesn't that work! Setting a parameter to another value should be illegal!"
-Steve
|
January 30, 2014 Re: Array as an argument, ambiguous behaviour. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On Thursday, 30 January 2014 at 16:18:33 UTC, Steven Schveighoffer wrote: > On Thu, 30 Jan 2014 11:04:44 -0500, Cooler <kulkin@hotbox.ru> wrote: > >> On Thursday, 30 January 2014 at 16:01:32 UTC, Cooler wrote: >>> On Thursday, 30 January 2014 at 15:59:48 UTC, Cooler wrote: >>>> On Thursday, 30 January 2014 at 15:51:44 UTC, Tobias Pankrath wrote: >>>>> On Thursday, 30 January 2014 at 15:49:35 UTC, Cooler wrote: >>>>>>>> I agree. I just want that the case can be expressed in language syntax more obvious - something like "fun(int[] const x){}" to emphasize that I understand that fun() can change content of array, and cannot change the {pointer,size} pair. >>>>>>> >>>>>>> That's what fun(int[] x) does :) >>>>>>> >>>>>>> -Steve >>>>>> >>>>>> Again... >>>>>> void fun(int[] x){ x ~= 5; } >>>>>> auto a = new int[10]; >>>>>> fun(a); // Can you predict the content of 'a'? >>>>> >>>>> >>>>> It's [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]. >>>> >>>> No!!! It depends how runtime allocates memory for the array. Read http://dlang.org/d-array-article.html. >>>> If 'a' has internal space enough to place '5' the caller will see >>>> [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5]. >>> >>> Sorry!!! My mistake. The caller will see [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] :) >> >> But that is the proof. The intention of fun() implementer will not be achieved. And such misunderstanding will appear only at runtime. > > void foo(int x) > { > x = 5; > } > > "hey, why doesn't that work! Setting a parameter to another value should be illegal!" > > -Steve Please understand - I am not against void foo(int[] x){} I am for predictability of behavior. You suggest to describe function's behavior in documentation - quotation from your article "It is a good idea to note in the documentation how the passed in slice might or might not be overwritten." My idea is that all potential errors must be detected as soon as possible. The D principle - "The program compile and runs as expected, or not compile at all". If you really need to call function that can change content of an array, but cannot change size of an array the language syntax should allow express it in function signature. I consider "void fun(int[] const x){}" more error prone than "void fun(int[] x){}" and for the caller and for implemeter. > I see very little value in that. We don't need to obliterate a tremendous amount of slice usage (not mentioning how much code will have to be updated) in order to help newbies understand how slices work. Any idea can be rejected by this sentence. |
January 30, 2014 Re: Array as an argument, ambiguous behaviour. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On Thursday, 30 January 2014 at 16:18:33 UTC, Steven Schveighoffer wrote:
> On Thu, 30 Jan 2014 11:04:44 -0500, Cooler <kulkin@hotbox.ru> wrote:
>
>> On Thursday, 30 January 2014 at 16:01:32 UTC, Cooler wrote:
>>> On Thursday, 30 January 2014 at 15:59:48 UTC, Cooler wrote:
>>>> On Thursday, 30 January 2014 at 15:51:44 UTC, Tobias Pankrath wrote:
>>>>> On Thursday, 30 January 2014 at 15:49:35 UTC, Cooler wrote:
>>>>>>>> I agree. I just want that the case can be expressed in language syntax more obvious - something like "fun(int[] const x){}" to emphasize that I understand that fun() can change content of array, and cannot change the {pointer,size} pair.
>>>>>>>
>>>>>>> That's what fun(int[] x) does :)
>>>>>>>
>>>>>>> -Steve
>>>>>>
>>>>>> Again...
>>>>>> void fun(int[] x){ x ~= 5; }
>>>>>> auto a = new int[10];
>>>>>> fun(a); // Can you predict the content of 'a'?
>>>>>
>>>>>
>>>>> It's [0, 0, 0, 0, 0, 0, 0, 0, 0, 0].
>>>>
>>>> No!!! It depends how runtime allocates memory for the array. Read http://dlang.org/d-array-article.html.
>>>> If 'a' has internal space enough to place '5' the caller will see
>>>> [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5].
>>>
>>> Sorry!!! My mistake. The caller will see [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] :)
>>
>> But that is the proof. The intention of fun() implementer will not be achieved. And such misunderstanding will appear only at runtime.
>
> void foo(int x)
> {
> x = 5;
> }
>
> "hey, why doesn't that work! Setting a parameter to another value should be illegal!"
>
> -Steve
Difference is here.
"void foo(int x){}" - the caller will NEVER see any change to 'x'.
"void foo(int[] x){}" - the caller MAY or MAY NOT see changes to 'x'.
|
January 30, 2014 Re: Array as an argument, ambiguous behaviour. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Cooler | On Thu, 30 Jan 2014 11:48:50 -0500, Cooler <kulkin@hotbox.ru> wrote: > > Please understand - I am not against void foo(int[] x){} From an earlier post by you: > May be just prohibit at language level the case of fun3() function, to do not allow unpredictable behavior? I thought that this meant you were against it? > I am for predictability of behavior. You suggest to describe function's behavior in documentation - quotation from your article "It is a good idea to note in the documentation how the passed in slice might or might not be > overwritten." My idea is that all potential errors must be detected as soon as possible. You cannot eradicate all errors. The intentions of a function are not apparent to the compiler. Maybe the intention is to use the argument as a buffer, and the caller should not care what happens to the buffer inside the function. Adding yet another attribute is going to increase language complexity for almost no benefit. It does not guarantee unambiguity because you have no idea what the author of the function is going to do. > The D principle - "The program compile and runs as expected, or not compile at all". This is a fantasy. The compiler cannot know what you expect. > If you really need to call function that can change content of an array, but cannot change size of an array the language syntax should allow express it in function signature. I consider "void fun(int[] const x){}" more error prone than "void fun(int[] x){}" and for the caller and for implemeter. Not sure if something is mixed up there. I think void fun(int[] x) is sufficient to describe what you say. The function cannot alter x's array bounds at all, and can alter it's data. > >> I see very little value in that. We don't need to obliterate a tremendous amount of slice usage (not mentioning how much code will have to be updated) in order to help newbies understand how slices work. > Any idea can be rejected by this sentence. No, only ideas that force people to change millions of lines of code, and provide scant benefits instead of taking 5 minutes to explain "no, just use x[0..2] = [1, 2]" or "just use ref int[] x" depending on the goal. -Steve |
January 30, 2014 Re: Array as an argument, ambiguous behaviour. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Cooler | On Thu, 30 Jan 2014 12:07:07 -0500, Cooler <kulkin@hotbox.ru> wrote: > On Thursday, 30 January 2014 at 16:18:33 UTC, Steven Schveighoffer wrote: >> void foo(int x) >> { >> x = 5; >> } >> >> "hey, why doesn't that work! Setting a parameter to another value should be illegal!" > > Difference is here. > "void foo(int x){}" - the caller will NEVER see any change to 'x'. > "void foo(int[] x){}" - the caller MAY or MAY NOT see changes to 'x'. This is incorrect: foo(int[] x){} - The caller will see changes to data 'x' references. A slice is a reference type, it references a specific block of data. It's more akin to a pointer than an int. I could change my example: void foo(int *x) { int n = 3; x = &n; } "hey, why doesn't x now point to 3? Should be illegal!" -Steve |
January 30, 2014 Re: Array as an argument, ambiguous behaviour. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Cooler | On Thursday, 30 January 2014 at 16:48:51 UTC, Cooler wrote: > On Thursday, 30 January 2014 at 16:18:33 UTC, Steven Schveighoffer wrote: >> void foo(int x) >> { >> x = 5; >> } >> >> "hey, why doesn't that work! Setting a parameter to another value should be illegal!" >> >> -Steve > > Please understand - I am not against void foo(int[] x){} > I am for predictability of behavior. Predictability of behavior is not a principle of D and even if it would be, it can't be applied blindly. D is not a formal mathematic system. > You suggest to describe function's behavior in documentation - quotation from your article "It is a good idea to note in the documentation how the passed in slice might or might not be > overwritten." My idea is that all potential errors must be detected as soon as possible. It is impossible to detect all errors in D per se, let alone taking into account separate compilation model. In some circumstances compiler can guess possible ways, but particular case we discussing is so common, that nothing can be done to 'fix' it. By the way, this case is not strictly speaking an error. It is error in context when caller cares about changes but this can be hardly verified at compile time (compiler need to read brain to know it). > The D principle - "The program compile and runs as expected, or not compile at all". It is all talk. Trying to apply this 'principle' in all cases is too naive. > If you really need to call function that can change content of an array, but cannot change size of an array the language syntax should allow express it in function signature. I consider "void fun(int[] const x){}" more error prone than "void fun(int[] x){}" and for the caller and for implemeter. > Personally this syntax is awful. By the way, there is another similar issue in D: import std.stdio; void foo(int[int] aa) { aa[1] = 1; } void main() { int[int] aa; foo(aa); writeln(aa); // [] aa[0] = 0; foo(aa); writeln(aa); // [0:0, 1:1] aa = null; foo(aa); writeln(aa); // [] } Here changes in AA array will be visible conditional that array is non null. If it is null, changes will be lost. This is another example of situation of "the caller MAY or MAY NOT see changes to" (citing your post above). In general, such semivalue-semireference semantic is produced when there is pointer wrapped into struct (doesn't matter whether it is opaque lang type or user defined). This happens in some language types, but may be also in user defined types. I don't think that verifying arbitrary semantic is compiler job. |
January 30, 2014 Re: Array as an argument, ambiguous behaviour. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | >> Please understand - I am not against void foo(int[] x){} > > From an earlier post by you: > >> May be just prohibit at language level the case of fun3() function, to do not allow unpredictable behavior? > > I thought that this meant you were against it? That was the question with "May be..." at the beginning. > >> I am for predictability of behavior. You suggest to describe function's behavior in documentation - quotation from your article "It is a good idea to note in the documentation how the passed in slice might or might not be >> overwritten." My idea is that all potential errors must be detected as soon as possible. > > You cannot eradicate all errors. The intentions of a function are not apparent to the compiler. Maybe the intention is to use the argument as a buffer, and the caller should not care what happens to the buffer inside the function. > > Adding yet another attribute is going to increase language complexity for almost no benefit. It does not guarantee unambiguity because you have no idea what the author of the function is going to do. > >> The D principle - "The program compile and runs as expected, or not compile at all". > > This is a fantasy. The compiler cannot know what you expect. The language is needed to express your intentions to the compiler. The language should be expressive as possible. My point is to push programmers to write correct software. I just ask these forum to think about topic. If everybody satisfied by void fun(int[] x){} behavior, then I just go... But I encounter a bug in my program that was due to my misusing of such signature. > >> If you really need to call function that can change content of an array, but cannot change size of an array the language syntax should allow express it in function signature. I consider "void fun(int[] const x){}" more error prone than "void fun(int[] x){}" and for the caller and for implemeter. > > Not sure if something is mixed up there. I think void fun(int[] x) is sufficient to describe what you say. The function cannot alter x's array bounds at all, and can alter it's data. > Here is the reason why i post the topic on this forum. You think one way, I think another way. I wanted to discuss what think other people. But looks like still nobody can understand my point, or may be I cannot express it... >> >>> I see very little value in that. We don't need to obliterate a tremendous amount of slice usage (not mentioning how much code will have to be updated) in order to help newbies understand how slices work. >> Any idea can be rejected by this sentence. > > No, only ideas that force people to change millions of lines of code, and provide scant benefits instead of taking 5 minutes to explain "no, just use x[0..2] = [1, 2]" or "just use ref int[] x" depending on the goal. > > -Steve |
Copyright © 1999-2021 by the D Language Foundation