DIP25 draft available for destruction
Zach the Mystic
reachBUTMINUSTHISzach at gOOGLYmail.com
Wed Feb 6 07:38:32 PST 2013
On Wednesday, 6 February 2013 at 07:38:17 UTC, Andrei
Alexandrescu wrote:
> Probably it'll need a fair amount of tweaking. Anyhow it's in
> destroyable form.
>
> http://wiki.dlang.org/DIP25
>
>
> Thanks,
>
> Andrei
All of the 'fine' ones are fine. Which leaves how one might
invoke the 'unfine' ones. The language must make a choice between
restricted simplicity and flexible complexity. If it chooses
flexibility, the function signature must give a clue as to what
the return value contains. 'out' return values and 'scope'
parameters will give the clues it needs.
Here are all the 'unfine' functions listed:
ref T gun(ref T);
struct S { int a; T b; }
ref S iun(ref S);
ref T caller(bool condition, ref T v1, ref S v2, T v3, S v4) {
T v5;
S v6;
// Not fine, bound to locals
// if (condition) return gun(v3);
// if (condition) return gun(v4.b);
// if (condition) return gun(v5);
// if (condition) return gun(v6.b);
// Not fine, bound to locals
// if (condition) return iun(v4);
// if (condition) return iun(v6);
}
Say gun's actual implementation is:
ref T gun(ref T a) {
auto noo = new T;
noo = a;
return noo;
}
You can' tell from the function signature that the return value
of this function is good to go, so the call 'return gun(v3);'
above would be disallowed even though it didn't need to be. If
you marked the signature with 'out', the caller knows it's good
to go, and the compiler can statically prevent the function from
returning one of its ref parameters. 'out' can be made to imply
'ref' in any case where the type is not inherently a reference
anyway.
out T gun(ref T a) {
return new T; // Pass
return a; // Error
}
This will solve all problems, except for the very rare corner
case when you need to assert fined-grained control over exactly
which ref parameters are safe and which are not. 'scope' comes to
the rescue here.
ref int fud(ref int a, scope int b) {
a += b;
return a; // Pass
return b; // Error
}
ref int elmer(ref int f) {
int v;
return fud(f, v); // Passes
return fud(v, f); // Fails
}
An 'out' return value simply marks all its 'ref' parameters
'scope' underneath the hood, so there will never be a need for
both 'out' and 'scope' in the same signature. Since 'scope' is
useless if its not a reference, it implies 'ref' also.
I'm pretty sure this is the best way to make the language
completely flexible. I don't anticipate an easier way to get it
done, and therefore, to my mind at least, the choice is between
simple-but-limited and flexible-and-complicated.
More information about the Digitalmars-d
mailing list