const challenge

Walter Bright newshound1 at digitalmars.com
Sat Feb 2 00:12:23 PST 2008


Oskar Linde wrote:
> I can't help but agree. The very first thing I tried when D 2.009 was 
> released was:
> 
> struct Vector { int x,y; }
> invariant Vector up = {0,1};
> void main() {
>     Vector y = up;
> }
> 
> which didn't work because:
>     Error: no property 'opCall' for type 'Vector'
> ??? No idea what that means. Is it trying to implicitly call a 
> non-existant struct static opCall "constructor"?

The issue here is assigning a mutable instance of Vector to an 
invariant. If Vector contained a pointer, then there's a big correctness 
hole. So then the issue is "since Vector does not contain any pointers, 
shouldn't this work?" The problem then is that if one builds code that 
uses Vector in this manner, and later the maintainer adds a pointer 
member variable to Vector, then all those uses of Vector break.

The reason for that particular error message is that because 
invariant(Vector) is not the same type as Vector, the compiler looks for 
an overload of the form:
	static invariant(Vector) opCall(Vector);


> and changing the main body to:
> 
>     Vector y;
>     y = up;
> 
> Yields:
>     Error: cannot implicitly convert expression (up) of type 
> invariant(Vector) to Vector

This, of course, is the reverse problem. If Vector contains a pointer, 
then copying an invariant pointer to a mutable pointer is a giant hole 
in correctness.


> Declaring constants using the "const" keyword is of course(?) wrong, 
> and: (I use the function call to illustrate the point, as just 
> initializing a variable gives the weird opCall error)
> 
> const Vector c = {1,1};
> void foo(invariant Vector v) {}
> void main() { foo(c); }
> 
> Yields:
>     Error: cannot implicitly convert expression (c) of type 
> const(Vector) to invariant(Vector)

const cannot be implicitly converted to either mutable or invariant, for 
the same reasons outlined above.


> And changing that to a "manifest constant":
> 
> enum Vector c = {1,1};
> 
> Yields:
>     Error: cannot implicitly convert expression (c) of type Vector to 
> invariant(Vector)
> 
> So, we have three different ways of declaring constants that are not 
> only incompatible with each other, but also incompatible with 
> non-constants. (This is what prompted me to post the "orthogonal const 
> proposal")
> 
> In my book, there are only two kinds of plain values. Constant and 
> variable. Why D needs 4 kinds is beyond me. Plain constant values should 
> always be implicitly convertible to non-constants. (Plain values are 
> values that contain no references to other data).

This is really the root issue here - should structs with references 
behave differently that structs without?


> Those examples only deal with plain values. Not a single reference is 
> included. If this design is final and D2 can't even handle values 
> properly I'm afraid there is not much attraction in D2 for me...
> 
> There are other issues with D2 const. Some I feel are quite serious and 
> others mainly aesthetic, but I can't be bothered to write about them 
> now. I don't even know why I bothered writing all this down. It is not 
> like I have any illusions about it making any difference what so ever.
> 
> In the meantime, D1 works well and remains a great language that is a 
> pleasure to use. ;)
> 



More information about the Digitalmars-d mailing list