May 24, 2007 Re: preparing for const, final, and invariant | ||||
---|---|---|---|---|
| ||||
Posted in reply to Regan Heath | == Quote from Regan Heath (regan@netmail.co.nz)'s article > Regan Heath Wrote: > > It seems to me you want both of these ('scope' because the reference will persist outside the function and 'final' because the very point of 'ref' is to be able to modify the reference) except in cases where you pass it by 'ref', in which case you want neither. > Re-reading this it appears I have made a mistake and worded it terribly to boot. To clarify... > What I was trying to say is twofold: > 1. Because we have 'ref' as an option then in the cases where we do not use 'ref' we do not need to modify the reference and therefore it should be 'final'. > 2. Because the reference is not passed by 'ref' it is a copy and will not persist outside the function and therefore is 'scope' > In short, unless you use 'ref' you want 'scope final' applied to these references. > Fingers crossed I haven't made any more mistakes there. > Regan Heath So wait...if I have a ref parameter, can I change the value of the reference locally without global changes? I like passing mutable copies of references. It's simple and expected behavior that I can count on. So will there be syntax that, for example, would give me the following? --- void func(char[] a) { a = a[1..$]; // good a[1] = 'f'; // error } --- For that, I'd just use final, correct? |
May 24, 2007 Re: preparing for const, final, and invariant | ||||
---|---|---|---|---|
| ||||
Posted in reply to gareis | gareis Wrote: > == Quote from Regan Heath (regan@netmail.co.nz)'s article > > Regan Heath Wrote: > > > It seems to me you want both of these ('scope' because the reference will > persist outside the function and 'final' because the very point of 'ref' is to be able to modify the reference) except in cases where you pass it by 'ref', in which case you want neither. > > Re-reading this it appears I have made a mistake and worded it terribly to boot. > To clarify... > > What I was trying to say is twofold: > > 1. Because we have 'ref' as an option then in the cases where we do not use > 'ref' we do not need to modify the reference and therefore it should be 'final'. > > 2. Because the reference is not passed by 'ref' it is a copy and will not > persist outside the function and therefore is 'scope' > > In short, unless you use 'ref' you want 'scope final' applied to these references. > > Fingers crossed I haven't made any more mistakes there. > > Regan Heath > > So wait...if I have a ref parameter, can I change the value of the reference locally without global changes? No, as that's the point of the 'ref' (the new name for 'inout') keyword, to explain.. void foo(ref char[] a) { a = "1,2,3"; } void main() { char[] b = "testing"; foo(b); writefln(b); } In the above 'b' is passed by reference to 'foo' (not a copy of 'b') which changes the value of the reference itself. This change can be seen when foo returns and 'b' is written to the console resulting in "1,2,3" instead of "testing". Remove 'ref' and you see "testing" on the console as "a = .." only modifies the copy of the original reference. In comparrison in Walters new sceme, assuming implicit 'in' meaning 'final const scope', eg. void foo(char[] a) { a = "1,2,3"; } void main() { char[] b = "testing"; foo(b); writefln(b); } you would get an error as the "a = .." line would violate the 'final' protection. > I like passing mutable copies of references. It's simple and expected behavior that I can count on. > > So will there be syntax that, for example, would give me the following? > --- > void func(char[] a) { > a = a[1..$]; // good > a[1] = 'f'; // error > } > --- > > For that, I'd just use final, correct? No, I think you'd use 'const scope'. In this thread we talked about having a new 'mutable' keyword which would mean 'const scope', eg. //these would be identical declarations void func(mutable char[] a) void func(const scope char[] a) My understanding, and I could be wrong here, is that 'final' protects the reference and 'const' protects the thing to which it refers. In the case of arrays: char[] aa; //global void func(char[] a) { a = a[1..$]; // violates final a[1] = 'f'; // violates const aa = a; //violates scope } In the case of classes: class A { int b; } A aa; //global void foo(A a) { a.b = 1; //violates const a = new A(); //violates final aa = a; //violates scope } Someone please correct me if I have this wrong/backward. Regan |
May 26, 2007 Re: preparing for const, final, and invariant | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | Walter Bright wrote: > Bill Baxter wrote: >> That makes sense to me too. If you don't say anything it's 'scope const final'. But if you do specify something then it's only that. > So the new 'in' would be the default if not specified, right? > Right. There are too many qualifies to do otherwise. > >> I'm not wild about the aesthetics of !const for parameters, and even less wild about the possibility that !const could become common idiom for modifiable parameters. If it's a common way to pass a parameter, then there should be a way to express the attribute positively (like "mutable" or "variable" or "inout") in terms of what it does do, rather than what it doesn't. > > Uh, I think you put a finger on just where I was getting a bad feeling about !const. It's generally confusing to use negatives as attributes, i.e., having state variables named: > "notFull" > is a bad idea. > > I'm at the moment thinking we should just bite the bullet and introduce 'mutable' as a keyword. A little late and FWIW, but this all sounds great to me! |
Copyright © 1999-2021 by the D Language Foundation