preparing for const, final, and invariant

Regan Heath regan at netmail.co.nz
Thu May 24 05:50:09 PDT 2007


gareis Wrote:
> == Quote from Regan Heath (regan at 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



More information about the Digitalmars-d-announce mailing list