Hmm - about manifest/enum
Christopher Wright
dhasenan at gmail.com
Wed Jan 2 17:26:45 PST 2008
Janice Caron wrote:
> But whatever the syntax, I must conclude that it can't be done,
> without violating one or more of the principles of D, and that's what
> Walter (and I) are trying to explain here.
You pick over cases where this is clearly the case; those where it is
not clear, you just say this and no more. You could at least provide a
link to the relevant discussions in webnews. Otherwise, I have no reason
to believe you and every reason to doubt.
>> If references are to be consistent, the
>> meaning of an int reference is that it acts like an int until you assign to
>> another int reference. If you assign it to another int reference, then type
>> now references the same thing as the new int reference. If you assign it to
>> another int, that is a compiler error (can't assign a non reference value to
>> a reference just like you can't assign a non pointer value to a pointer).
>
> D doesn't have a reference-to-int type, only reference-to-class-data.
We do, actually: int*.
> This appears to be a new feature request.
Yup. Because it looks kludgy to use const(T)*, and it looks kludgy to
use const(T), and so I'm betting const will be used as often in D as in C++.
>> One further thing. If you could at least pledge to have a way to specify a
>> tail-const class reference before 2.0 is officially released, I would be
>> willing to accept that for now.
>
> Walter cannot do that without sacrificing generic programming.
Well, the thing is, we already have a technique to get tailconst
anything, and that's using a pointer. As far as I can tell, people just
want a prettier syntax for using mutable pointers to const data, and an
equivalent to const(Object)* that involves one pointer dereference
instead of two to access the object. Pretty syntax isn't a minor thing,
either.
Also, there's the problem, with pointers:
const(T)*[] array = init_array();
array.sort; // sorts according to pointer values -- eep!
This can mess with generic programming, too:
struct S { int i; }
void reset_first_element(T)(array[] array) {
static if (is (T == class)) {
array[0] = new T();
} else {
array[0] = T.init;
}
}
const(S)*[] array = init_array();
reset_first_element(array);
(channeling Gunther Hermann)
I wanted *array[0] == S.init.
It gave me segmentation fault.
Then the 'right' way would be something like:
void reset_first_element(T)(array[] array) {
static if (is (T == class)) {
array[0] = new T();
} else static if (is (T == const(U)*, U)) {
static if (is (T == class)) {
*array[0] = new U();
} else {
*array[0] = U.init;
}
} else {
array[0] = T.init;
}
}
And that doesn't distinguish between situations where I want a reference
and I want an actual pointer.
Basically, references solve a bunch of problems with const and with
generic programming. The previous example becomes:
void reset_first_element(T)(array[] array) {
static if (is (T == class)) {
array[0] = new T();
} else static if (is (T == U&, U)) {
array[0] = U.init;
} else {
array[0] = T.init;
}
}
Or maybe, depending on what T&.init is, you could eliminate the second
element.
C# did something clever: for any value type T, new T() returns T.init.
This makes sense; for value type T, T.init is usually sensible, or at
least a lot more useful than null. So you'd get:
void reset_first_element(T)(array[] array) {
static if (is (T == U&, U)) {
array[0] = new U();
} else {
array[0] = new T();
}
}
Or even:
void reset_first_element(T)(array[] array) {
array[0] = new T();
}
Whether it's desirable for D is another matter.
More information about the Digitalmars-d
mailing list