Here are my two cents:

First, about optional parentheses:

Optional parentheses = ambiguity.

int foo() { return 4; }
auto x = foo; // gives 4 or gives function foo?

It seems to me any ambiguity should be an error. However… it only matters when the type system can't provide the missing detail, as above.

The ambiguity may be resolved either in the function signature or at the call site. @property partly helps resolve it at the function signature, but it is a different issue from optional parentheses.

Ambiguity can also be resolved at the call site instead of the function signature. It needs to be as clear and concise as possible in addition to being unambiguous. D's method of disambiguating cases often uses the keyword "cast". Applying it in this case would lead to "cast(function)" or "cast(delegate)" to indicate the function and not the return value, where the default is to indicate the return value.

int foo() { return 4; }
int function() goo() { return foo; }

auto doh = foo(); // gives 4
auto go = foo; // Error: can't deduce type of expression foo
auto fun = cast(function) foo; // gives foo

auto ae = goo; // Error: can't deduce type (either goo or function int() foo )
auto fe = goo(); // Error: can't deduce type (either foo or 4)
auto ga = goo()(); // gives 4
auto gu = cast(function) (goo()); // gives foo
auto gi = cast(function) goo; // gives goo

This solution is unambiguous and clear, but unfortunately not very concise. In fact, "cast(function) foo" is rather a long way of saying "&foo", but much clearer and possibly safer. The type system can probably resolve most of these ambiguities anyway, which would mean the cast wouldn't appear very often, but I'm not sure.

I have no real opinion about @property. Ideally the compiler could deduce what is and isn't a property without the ugly @property attached to all the signatures, but it might invite so many abuses of this process that it's not worth it.

Reply via email to