Revised RFC on range design for D2
Andrei Alexandrescu
SeeWebsiteForEmail at erdani.org
Mon Sep 29 06:48:31 PDT 2008
Michel Fortin wrote:
> Ok, great. What do you do with this by the way:
>
> struct S2
> {
> void prop(int x);
> deprecated int prop();
> }
>
> Did the author want to eventually replace "prop()" with "prop() = void"
> to keep allowing "prop = 1", or does he want to simply remove it and
> disallow the "prop = 1" syntax?
>
> I find it somewhat troubling that removing an unused function
> (especially if private) could invalidate code just because it is calling
> another overloaded function with the property syntax. I mean, now to
> know if you can safely remove a function, you have to check if anyone is
> using any of corresponding overloaded "setters" too.
I understand. I find it somewhat troubling too.
>> void generic(Node)(Node obj) {
>> auto save = obj.indentLevel;
>> scope(exit) obj.indentLevel = save;
>> ...
>> }
>
> Hum, but if the setter is private, protected, or package, or if it just
> doesn't exist, that guarenty doesn't exist.
That means indentLevel is not a property and consequently "generic"
cannot work with that object.
> Another interesting case:
>
> struct S5
> {
> int prop();
> void prop(int x) const;
> }
>
> Not sure what to do with it though, but it certainly breaks your
> guarenty when S5 is invariant. So should the property syntax "s5.prop =
> x;" works only when S5 is mutable, or not at all, or in all cases?
It's very simple. If you have "entity.prop = x" first you check for
"entity.prop(entity.prop)". Does that compile? If so, you rewrite
"entity.prop = x" as entity.prop(x) and continue from there. In your
question s5 can be invariant, const, or mutable. In either case the
usual judgment applies.
> Then what about this strange one:
>
> struct S5
> {
> int prop();
> string prop() invariant;
> void prop(int x) const;
> }
>
> Should the property syntax works when for S5, const(S5), invariant(S5) ?
Same answer.
>>> Then you should probably disallow "ref" and "out" too in the setter.
>>
>> Consider:
>>
>> struct ArrayAppender {
>> ref Array host;
>> void host(ref Array);
>> }
>>
>> That should work as property, ain't it?
>>
>> (Walter has introduced ref returns; I'm already working on an alpha
>> that has the feature. Of course I found bugs, too. :o))
>
> And "out"?
struct S {
ref int prop();
void prop(out int);
}
s.prop(s.prop) does compile, so s.prop = x; should be allowed. However,
I agree it does something counterintuitive (modify the right-hand side).
> Ok, let's clarify that:
>
> struct S1
> {
> int prop();
> static void prop(int x);
> }
>
> struct S2
> {
> static int prop();
> void prop(int x);
> }
>
> S1 s1;
> s1.prop = 1; // ok, because s1.prop returns int.
> S1.prop = 1; // error, since S1.prop does not exist.
>
> S2 s2;
> s2.prop = 1; // ok, because s1.prop returns int.
>
> Is that right?
Yah.
>>> And what if you have an invariant(S2) and prop(Object x) is
>>> accessible (because it is invariant) while prop() is not (because not
>>> invariant), should the "=" syntax apply anyway?
>
> No answer to that one? Take this case:
>
> struct S3
> {
> int prop() invariant;
> void prop(int x);
> }
>
> S3 s3;
> s3.prop = x; // error?
s3.prop(s3.prop) would not compile, so neither does the assignment form.
> struct S4
> {
> int prop();
> void prop(int x) invariant;
> }
>
> invariant(S4) s4;
> s4.prop = x; // error?
>
> I guess disallowing this wouldn't be too bad, since it's pretty
> ridiculous anyway.
This would not compile because s4.prop(s4.prop) does not compile.
> The thing is that you can't explain everything just by checking if you
> can compile "s.prop(s.prop)". If one of the two is private, you said it
> would be allowed anyway, it becomes "s.prop(s.prop) disregarding
> applicable protection attributes". Then you said that it the getter
> could be "= void", but obviously "s.prop(s.prop) wouldn't compile in
> that case, so you'd have to change it to "s.prop(s.prop) compiles
> disregarding applicable protection attributes and whether or the the
> getter is '= void'". Then you'll need to add something about the
> constness of the struct or class the function is scoped in, so it becomes:
>
> s.prop(s.prop) compiles disregarding applicable protection attributes,
> disregarding whether or the the getter is '= void', and disregarding
> the constness of the enclosing scope (class or struct).
>
> That doesn't sound so simple, and I probably got it wrong. Can you
> define it better?
With this part I completely disagree. You artificially create complexity
by bringing other rules into play that were in place before this
discussion. By the same token you could add "s.prop(s.prop) compiles if
s and prop are properly formed identifiers" and claim that that is an
issue with properties.
The protection attributes do their job. The = void does (will do,
actually) its job. Qualifiers do their job. It's business as usual. I
did not invent those rules for the sake of properties.
Andrei
More information about the Digitalmars-d-announce
mailing list