@property - take it behind the woodshed and shoot it?

deadalnix deadalnix at gmail.com
Thu Jan 24 05:41:41 PST 2013


On Thursday, 24 January 2013 at 08:35:01 UTC, Walter Bright wrote:
> This has turned into a monster. We've taken 2 or 3 wrong turns 
> somewhere.
>

I'm so happy to read this !!!!

> Perhaps we should revert to a simple set of rules.
>
> 1. Empty parens are optional. If there is an ambiguity with the 
> return value taking (), the () go on the return value.
>
> 2. the:
>    f = g
> rewrite to:
>    f(g)
> only happens if f is a function that only has overloads for () 
> and (one argument). No variadics.
>
> 3. Parens are required for calling delegates or function 
> pointers.
>
> 4. No more @property.

I'm so unhappy to read this :(((((((

Ok let me be more constructive. The current state of thing have 2 
issues : on is that non properties are conflated with properties, 
and the other is that setter is conflated with getter.

You solution isn't good because it conflate things even more. 
Here is my proposal :

For regular functions :
1. funName is the function itself :
   void funName() {}
   static assert(is(typeof(funName) == void function())); // Pass.
   funName has no address, it is equivalent to enum function 
void() funName = {};
   &funName become a NOOP and is deprecated, for compatibility 
reasons. It is not ambiguous as funName has no address anyway.

2. funName() call the function.

Rationale : function as variable or defined in the source now 
behave the same way (expect the deprecated & behavior). It makes 
it easier to write generic code, and in general consistency is a 
plus (easier to learn the language, less dark corner case to 
consider, easier interaction with other features).

3. @getter is an attribute. A function marked @getter is 
automatically executed : () is added automatically :
     @getter void funName() {}
     funName; // function get executed.
     funName(); // Error, void is not callable.

4. @getter can be used as UFCS.
    @getter void funName(T t) {}
    T t; t.funName; // function gets executed.
    funName(t); // Error, funName require 1 argument, 0 given.

5. @setter is an attribute. A setter method can *only* be used in 
rhs of an expression. The assigned value is used as argument.
    @setter void funName(T t) {}
    T t; funName = t; // function gets executed.
    funName(t); // Error, funName must be used in an assign 
expression.

6. @setter can as well be used as UFCS :
    @getter void funName(T t, U u) {}
    T t; U u; t.funName = u; // function gets executed.
    t.funName(u); // Error, funName must be used in an assign 
expression.

7a. A function can be defined as both @setter and @getter, and 
cumulate both behavior.
7b. @property is deprecated and redefined as @setter *and* 
@getter for a transitional period.

8. method behave as functions :
     class A { void foo() {} }
     A a;
     static assert(is(typeof(a.foo) : void delegate())); // Pass.
     &a.foo; // deprecated NOOP for compatibility.
     a.foo(); // call a.foo

9. UFCS without () are delegate like construct :
     void foo(T t) {}
     T t; t.foo; // Is a struct with a function pointer and t. 
(equivalent to a delegate). The struct member's type is the same 
as the first argument. If a copy is necessary postblit is called 
- but will not be called at function call. If foo take a 
reference, a pointer is stored.
     t.foo(); // call foo with t as parameter.

10. To allow chain of UFCS calls without () everywhere, an 
opDispatch is defined in object.d : the function/delegate get's 
called and the result is used as parameter for foo. This 
eliminate the need for () on all functions of an UFCS chain 
expect the last one, which is a price to pay for cleanly defined, 
unambiguous semantic.

Waiting for the shitstorm . . .


More information about the Digitalmars-d mailing list