On 02/08/2013 05:22 AM, deadalnix wrote:
...

You have the following behavior :
  - & take the address of what is before.
  - foo is call to function foo.
  - special case : &foo

foo();
foo!()
tmpl!foo
alias sym=foo;

is the first class function foo. (here expression foo have a new meaning).

Again, & behaves like that even for variables.

auto x = 5;
auto y = &5;  // error
auto z = &x;  // ergo: this 'x' is different
assert(x==5); // from this one

  - In a comma expression, if the last item is a function, it is
evaluated, unless the comma expression is in an address of context, in
which case the function pointer is returned.
  - Same goes for ternary, except that both branches are evaluated in
that context.

This is exactly how special case (3) turtle down to definition of many
other languages constructs.

I think ternary and comma is a comprehensible list of the many other language constructs.

For instance,

int a;
int foo() { return a }

static assert(is(typeof(foo) == typeof(a))); // Pass
condition ? foo : a; // OK.
&(condition ? foo : a); // Type error between foo of unexpressible type
(static array of instructions)

(This does not make any sense. Instructions are often variable-size.)

and a of type int.

The error message is a QOI issue. This is what DMD reports if foo is a double, and a is an int:

Error: cast(double)a is not an lvalue
Error: cannot implicitly convert expression (condition ? & foo : (__error)) of type double* to double*

(Another point: As you may have noticed, the constructs &(a?b:c) and &(a,b) are "special cased" _anyway_.)

IMHO this is roughly what should be reported in both the case that foo is a function and that foo is a double, maybe giving away a little more information:

error: cannot take address of expression '(condition ? foo : a)'
    &(condition ? foo : a);
    ^~~~~~~~~~~~~~~~~~~~~~

I think DIP24 is a valid way to go.

The simplest alternative design I'd be fine with would be to remove @property, mandate parens on non-ufcs calls, identify function names with their function pointers/delegates, disallow foo = functionArgument and &foo for foo a function or method, and call it a day.

(This would not simplify lvalue/rvalue rules, but reduce the number of cases where they apply.)

Reply via email to