@property needed or not needed?

Artur Skawina art.08.09 at gmail.com
Thu Dec 6 07:36:03 PST 2012


On 12/03/12 03:23, kenji hara wrote:
> I had been trying to advance the phase to the next.
> Now, an experimental pull request is here.
> https://github.com/D-Programming-Language/dmd/pull/1311
> 
> ----
> This change can distinguish almost usages between property and non-property syntax 
> 
> int func() { return 1; }
> void func(int n) { }
> @property int prop() { return 2; }
> @property void prop(int n) { }
> void main() {
>   // Without -property switch, all lines can compile.
>   // With -property switch:
>   func();     // OK -> OK
>   func(1);    // OK -> OK
>   func;       // OK -> OK [*]
>   func = 1;   // OK -> NG (fixed!)
>   prop();     // OK -> NG (fixed!)
>   prop(1);    // OK -> NG (fixed!)
>   prop;       // OK -> OK
>   prop = 1;   // OK -> OK
> }
> 
> First exception is [*], keeping the line is necessary to allow UFCS chain without redundant parentheses (e.g. r.map!(a=>a*2).array). It is acceptable to me, at least.

Reasonable middle-term compromise; can't really disallow ()-ess calls
w/o something else to migrate to, which doesn't exist yet.


> I also implemented that calling function pointer which returned by property function.
> 
> @property foo(){ return (int n) => n * 2; }
> auto n = foo(10);  // `foo` is resolved to property function call in advance
> assert(n == 20);
> 
> But, we cannot support it immediately, because it will *always* introduce breaking of existing code.
> 
> - If enable always this feature, propfunc() is implicitly translated to (propfunc())(),
>   then much existing correct code without "-property" switch will break.
> - If enable this only when -property switch is specified, a code propfunc() will have
>   _two_ meanings. When propfunc returns a function pointer,
>   * If -property is on, propfunc() is translated to propfunc()(), then
>     call returned function pointer and returns its result.
>   * If -property is off, propfunc() is jsut call property function, then
>     returns function pointer.
> 
> Changing compilation behavior by compile switch is bad.

'Bad' doesn't begin to describe it. It's unacceptable, as such a compiler
switch would create a different language.
So it has to be the first option. Which isn't that bad as the "correct" term
isn't really appropriate here. This /is/ a change that will break legacy code,
but the failures should happen mostly at compile time and the fix is both
trivial and backwards compatible.
Delaying these kind of changes would only make things worse.


> The third exception is in AddressExpression (&exp).
> 
> In current, both &func and &propfunc return their function pointers. Some peoples argues
> that the latter should return an address of the returned value of propfunc after implementing more property enforcement, but I'm difficult to accept that.
> 
> The root cause is: AddressExpression is just only one built-in feature for getting an exact type of property function (Note that typeof(propfunc) returns the type of propfunc result).
> 
> If compiler will always translate the code &propfunc to &(propfunc()), 
> we will lost a way to get an exact type of propfunc, and then std.traits.FunctionTypeOf will never work for propfunc.
> 
> To resolve the issue, I have proposed a small enhancement for AddressExpression.
> http://d.puremagic.com/issues/show_bug.cgi?id=9062 
> 
> It will distinguish &propfunc and &(propfunc), the former returns a function poiinter of propfunc, and the latter returns an address of propfunc result.

No, extremely bad idea; parens shouldn't make any difference.

   &cast(function)prop // or 'cast(delegate)', as appropriate


> The real example about that is here.
> https://github.com/D-Programming-Language/phobos/pull/968/files#L0L1136 
> 
> ----
> How about that?

The property situation is as bad as it is in part because the migration was
handled wrongly. What should have happened is that the 'property' compiler
switch should have enabled legacy code to compile and property enforcement
should have been on by default, to the extent supported by the compiler.
Doing it the other way meant that people are writing incorrect code even 
today. [1]
Your changes seem to go in the right direction. Committing to such property
enforcement will however be necessary, as keeping the current optional
status forever won't work, because of issues like the ones you list above.

artur

[1] Yeah, "incorrect" means /just/ "incompatible with property enforcement".
    But the alternative is /no/ enforcement, and if you believe that to be
    the right approach then every trace of @property should go.


More information about the Digitalmars-d mailing list