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