DIP23 Counter Proposal

Timon Gehr timon.gehr at gmx.ch
Fri Feb 8 08:22:39 PST 2013


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.)



More information about the Digitalmars-d mailing list