On 01/25/2012 02:29 AM, H. S. Teoh wrote:
On Tue, Jan 24, 2012 at 08:01:41PM -0500, bearophile wrote:
Jonathan M Davis:

Now, the confusing part is the fact that unlike C++, D allows you to put the
const for making the function on the _left-hand_ side of the function (C++
only lets you put it on the right). This is to increase consistency between
modifers (public, override, pure, etc.) - they _all_ can go on both the right
and left (which is very unfortunate in the case of const and immutable IMHO).
That means that const (and immutable) always modify the function rather than
the return value unless you use parens.

Some time ago we have discussed this topic in an enhancement request in 
Bugzilla. The idea was to disallow code like:


struct Foo {
     int x;
     const const(int) bar() {
         return 0;
     }
}
void main() {}


and require the struct "const", "immutable" to be only on the right if present.
Walter shot this idea down for consistency. But I generally don't want
consistency when it's just a potential source of confusion for the
programmer :-)
[...]

How can this be consistency? For example:

        class A {
                const int x;
                @property const int y();
        }

Now you have typeof(A.x)==const(int) and typeof(A.y)==int. Seems quite
inconsistent to me.

But since Walter doesn't like the idea of restricting the syntax to 'int
y() const', then what about making it mandatory to write:

        const(int) x;

instead of:

        const int x;

?

You essentially propose to remove the const/immutable/shared/inout storage classes for variables. It would break almost every D program and I don't see many benefits.

Requiring the parentheses is a bit extreme, I admit, but it touches upon
another area of D syntax that I don't quite like, and that is const or
immutable applied to arrays:

        const(int)[] x;         // array of const(int)
        const(int[]) x;         // const array of int
        const int[] x;          // ??? const array of const int? Or one
                                // of the above?

const(int[]).


The storage class of a declaration applies to the whole declaration.

It gets worse when you throw in ref:

Ref does not change anything but the calling convention *of the function*. The reference itself cannot be rebound, there is no syntax for it.


        ref int f();            // returns int* (I think?)
        ref const(int) f();     // returns const(int)* (?)
        ref const int f();      // ???
        const ref int f():      // ???

The last line is quite bad. Is the return type const(int*) or
const(int)*, or is it just int* (i.e., const applies to f not the return
value)?

It is int.


        ref const(int)[] x;     // ref to array of const(int)?

Note that ref can only be on a function or on a parameter.

        const(ref int)[] x;     // array of refs to int?

No such thing exists.

        const ref int[] x;      // array of ???

const(int[]). Declaration is invalid, would have to be a parameter.

        const ref int[] x();    // const function that returns ref int[]?

It returns int[], by reference. It is equivalent to

int[] x()const ref;

Though most people will prefer to have 'ref' on the lhs:

ref int[] x()const;

It still applies to the function though.

        const const ref int[] x();      // const function returning what?

Redundant storage class const.

ref int[] x()const const; is the same thing.


The more I think about this, the more confusing it becomes.

It is very simple. What may be confusing you is that const/immutable/shared/inout are both type constructors and storage classes.

If
parentheses were mandatory after const, things would be much, much
better:

        const(ref int) x;
        const(ref const(int)) x;
        ... etc.

Much clearer to me.

It is not to me. This is not valid syntax. Also, types of the general form const(...const(...)...) don't make a lot of sense. Const is transitive.

Reply via email to