Thread overview | |||||||
---|---|---|---|---|---|---|---|
|
August 04, 2004 free functions as attributes | ||||
---|---|---|---|---|
| ||||
Given this code: # void attribute( char[] c ) {} # void attribute( char c ) {} # # int main() # { # char[] ary; # ary.attribute(); // (1) works # ary.attribute; // (2) no property 'attribute' for type 'char[]' # # char c; # c.attribute(); // (3) no property 'attribute' for type 'char' # c.attribute; // (4) no property 'attribute' for type 'char' # return 0; # } I'd like to request some consistency. If (1) works, then (3) should work as well. And ideally, all four examples should work if this syntax is to be supported. It seems odd that arrays are an exception in this case. Sean |
August 04, 2004 Re: free functions as attributes | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean Kelly | Sean Kelly wrote:
> Given this code:
>
> # void attribute( char[] c ) {}
> # void attribute( char c ) {}
> # # int main()
> # {
> # char[] ary;
> # ary.attribute(); // (1) works
> # ary.attribute; // (2) no property 'attribute' for type 'char[]'
> # # char c;
> # c.attribute(); // (3) no property 'attribute' for type 'char'
> # c.attribute; // (4) no property 'attribute' for type 'char'
> # return 0;
> # }
>
> I'd like to request some consistency. If (1) works, then (3) should work as
> well. And ideally, all four examples should work if this syntax is to be
> supported. It seems odd that arrays are an exception in this case.
It looks handy, but I can't help but think that it's begging to introduce non-obvious behaviour into seemingly straightforward code.
I think it would be prudent to leave the rules as they are and see what happens. When work on D 2.0 starts, it can be decided whether it should be removed or extended. (or neither)
I do think one small change should be made, however:
This behaviour should only occur when the first argument of the function is inout.
Things are just begging to get weird if a function mutates an array in some manner and is passed as an 'in' parameter under normal circumstances. Hiding it behind method-like syntax would only make it worse: you don't expect 'real' methods to reallocate the 'this' reference part-way through. :)
-- andy
|
August 04, 2004 Re: free functions as attributes | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andy Friesen | On Wed, 04 Aug 2004 14:19:29 -0700, Andy Friesen <andy@ikagames.com> wrote: > Sean Kelly wrote: >> Given this code: >> >> # void attribute( char[] c ) {} >> # void attribute( char c ) {} >> # # int main() >> # { >> # char[] ary; >> # ary.attribute(); // (1) works >> # ary.attribute; // (2) no property 'attribute' for type 'char[]' >> # # char c; >> # c.attribute(); // (3) no property 'attribute' for type 'char' >> # c.attribute; // (4) no property 'attribute' for type 'char' >> # return 0; >> # } >> >> I'd like to request some consistency. If (1) works, then (3) should work as >> well. And ideally, all four examples should work if this syntax is to be >> supported. It seems odd that arrays are an exception in this case. > > It looks handy, but I can't help but think that it's begging to introduce non-obvious behaviour into seemingly straightforward code. > > I think it would be prudent to leave the rules as they are and see what happens. When work on D 2.0 starts, it can be decided whether it should be removed or extended. (or neither) > > I do think one small change should be made, however: > > This behaviour should only occur when the first argument of the function is inout. > > Things are just begging to get weird if a function mutates an array in some manner and is passed as an 'in' parameter under normal circumstances. Hiding it behind method-like syntax would only make it worse: you don't expect 'real' methods to reallocate the 'this' reference part-way through. :) If an array is passed as 'in' (the default) you cannot change the array reference, you can change the data, append to the data, change the length, etc.. the 'this' reference is the array reference, and it cannot be changed, so I don't understand what you're saying. Regan -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/ |
August 04, 2004 Re: free functions as attributes | ||||
---|---|---|---|---|
| ||||
Posted in reply to Regan Heath | Regan Heath wrote:
> On Wed, 04 Aug 2004 14:19:29 -0700, Andy Friesen <andy@ikagames.com> wrote:
>
>> Sean Kelly wrote:
>>
>>> Given this code:
>>>
>>> # void attribute( char[] c ) {}
>>> # void attribute( char c ) {}
>>> # # int main()
>>> # {
>>> # char[] ary;
>>> # ary.attribute(); // (1) works
>>> # ary.attribute; // (2) no property 'attribute' for type 'char[]'
>>> # # char c;
>>> # c.attribute(); // (3) no property 'attribute' for type 'char'
>>> # c.attribute; // (4) no property 'attribute' for type 'char'
>>> # return 0;
>>> # }
>>>
>>> I'd like to request some consistency. If (1) works, then (3) should work as
>>> well. And ideally, all four examples should work if this syntax is to be
>>> supported. It seems odd that arrays are an exception in this case.
>>
>>
>> It looks handy, but I can't help but think that it's begging to introduce non-obvious behaviour into seemingly straightforward code.
>>
>> I think it would be prudent to leave the rules as they are and see what happens. When work on D 2.0 starts, it can be decided whether it should be removed or extended. (or neither)
>>
>> I do think one small change should be made, however:
>>
>> This behaviour should only occur when the first argument of the function is inout.
>>
>> Things are just begging to get weird if a function mutates an array in some manner and is passed as an 'in' parameter under normal circumstances. Hiding it behind method-like syntax would only make it worse: you don't expect 'real' methods to reallocate the 'this' reference part-way through. :)
>
>
> If an array is passed as 'in' (the default) you cannot change the array reference, you can change the data, append to the data, change the length, etc.. the 'this' reference is the array reference, and it cannot be changed, so I don't understand what you're saying.
Actually I'm not sure if I agree with what I wrote when I posted that, but what I meant was that, if you wrote something like this:
import std.stdio;
void dupe(char[] This, char[] str, int count) {
for (int i = 0; i < count; i++) {
This ~= str;
}
}
int main() {
char[] ni;
ni.dupe("NI!", 999); // set ni to "NI!NI!NI!....."
writefln(ni);
return 0;
}
You'd be in for a surprise. The string 'ni' is not going to change, because all those concatenations are more than enough to cause D to reallocate the array. Since 'This' is not an inout parameter, the reallocation isn't reflected back to the argument passed.
But, I don't think this is such a great idea anymore. This wrinkle in the language is, as far as I know, used primarily for string functions, which typically don't mutate strings in-place anyway.
-- andy
|
August 05, 2004 Re: free functions as attributes | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andy Friesen | On Wed, 04 Aug 2004 16:50:53 -0700, Andy Friesen <andy@ikagames.com> wrote: > Regan Heath wrote: > >> On Wed, 04 Aug 2004 14:19:29 -0700, Andy Friesen <andy@ikagames.com> wrote: >> >>> Sean Kelly wrote: >>> >>>> Given this code: >>>> >>>> # void attribute( char[] c ) {} >>>> # void attribute( char c ) {} >>>> # # int main() >>>> # { >>>> # char[] ary; >>>> # ary.attribute(); // (1) works >>>> # ary.attribute; // (2) no property 'attribute' for type 'char[]' >>>> # # char c; >>>> # c.attribute(); // (3) no property 'attribute' for type 'char' >>>> # c.attribute; // (4) no property 'attribute' for type 'char' >>>> # return 0; >>>> # } >>>> >>>> I'd like to request some consistency. If (1) works, then (3) should work as >>>> well. And ideally, all four examples should work if this syntax is to be >>>> supported. It seems odd that arrays are an exception in this case. >>> >>> >>> It looks handy, but I can't help but think that it's begging to introduce non-obvious behaviour into seemingly straightforward code. >>> >>> I think it would be prudent to leave the rules as they are and see what happens. When work on D 2.0 starts, it can be decided whether it should be removed or extended. (or neither) >>> >>> I do think one small change should be made, however: >>> >>> This behaviour should only occur when the first argument of the function is inout. >>> >>> Things are just begging to get weird if a function mutates an array in some manner and is passed as an 'in' parameter under normal circumstances. Hiding it behind method-like syntax would only make it worse: you don't expect 'real' methods to reallocate the 'this' reference part-way through. :) >> >> >> If an array is passed as 'in' (the default) you cannot change the array reference, you can change the data, append to the data, change the length, etc.. the 'this' reference is the array reference, and it cannot be changed, so I don't understand what you're saying. > > Actually I'm not sure if I agree with what I wrote when I posted that, but what I meant was that, if you wrote something like this: > > import std.stdio; > > void dupe(char[] This, char[] str, int count) { > for (int i = 0; i < count; i++) { > This ~= str; > } > } > > int main() { > char[] ni; > ni.dupe("NI!", 999); // set ni to "NI!NI!NI!....." > > writefln(ni); > return 0; > } > > You'd be in for a surprise. The string 'ni' is not going to change, because all those concatenations are more than enough to cause D to reallocate the array. Since 'This' is not an inout parameter, the reallocation isn't reflected back to the argument passed. I don't think it matters whether it reallocates or not, I think it's simply a matter of the original string having a length of 0 and the modified data (if not reallocated) being longer than that. You can however modify a character within the original string length and that change is reflected back to the argument passed. See my test case below. > But, I don't think this is such a great idea anymore. This wrinkle in the language is, as far as I know, used primarily for string functions, which typically don't mutate strings in-place anyway. The current concept makes me slightly uncomfortable for no reason I can put into words. I still think 'in' should enforce 'const', and there should be a way to specify const data that an array references, which cannot be changed by any reference to that data. import std.stdio; void addOne(char[] s) { s.length = s.length+1; s[s.length-1] = 'A'; } void changeOne(char[] s) { s[0] = s[0]+1; } int main() { char[] ni = "NO!"; ni.length = 100; ni.length = 3; addOne(ni); writefln(ni); changeOne(ni); writefln(ni); return 0; } Regan. -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/ |
Copyright © 1999-2021 by the D Language Foundation