www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Invariant Question (yes, another one)

reply "Janice Caron" <caron800 googlemail.com> writes:
I got this error...

Error: cannot implicitly convert expression (aa) of type
invariant(char)[][invariant(char)[]] to const(char)[][const(char)[]]

Why not?

Since invariant(char)[] can implicitly convert to const(char)[], I
just don't see a problem with this.
Nov 15 2007
next sibling parent reply Xinok <xnknet gmail.com> writes:
Const is the read-only type, meaning that the data COULD change 
unexpectedly. However, invariant means the data is guaranteed never to 
change. You can't guarantee const data is never going to change, which 
is why it gives you an error.

Janice Caron wrote:
 I got this error...
 
 Error: cannot implicitly convert expression (aa) of type
 invariant(char)[][invariant(char)[]] to const(char)[][const(char)[]]
 
 Why not?
 
 Since invariant(char)[] can implicitly convert to const(char)[], I
 just don't see a problem with this.
Nov 15 2007
parent reply "Janice Caron" <caron800 googlemail.com> writes:
On 11/15/07, Xinok <xnknet gmail.com> wrote:
 Const is the read-only type, meaning that the data COULD change
 unexpectedly. However, invariant means the data is guaranteed never to
 change. You can't guarantee const data is never going to change,
I know that. You're stating the obvious.
 which
 is why it gives you an error.
I don't follow that reasoning. Please explain in more detail. invariant(char)[] can always be implicitly cast to const(char)[] ... and that's exactly what I'm trying to do.
Nov 15 2007
next sibling parent reply Matti Niemenmaa <see_signature for.real.address> writes:
Janice Caron wrote:
 On 11/15/07, Xinok <xnknet gmail.com> wrote:
 Const is the read-only type, meaning that the data COULD change
 unexpectedly. However, invariant means the data is guaranteed never to
 change. You can't guarantee const data is never going to change,
I know that. You're stating the obvious.
 which
 is why it gives you an error.
I don't follow that reasoning. Please explain in more detail. invariant(char)[] can always be implicitly cast to const(char)[] ... and that's exactly what I'm trying to do.
If I understood correctly: An invariant variable cannot change, period. If you cast an invariant variable to const, and then change it through the const variable (this bit seems dubious to me), the invariant variable has changed. But this isn't permissible. Hence, you can't cast invariant to const. -- E-mail address: matti.niemenmaa+news, domain is iki (DOT) fi
Nov 15 2007
parent "Janice Caron" <caron800 googlemail.com> writes:
On 11/15/07, Matti Niemenmaa <see_signature for.real.address> wrote:
 If I understood correctly:

 An invariant variable cannot change, period. If you cast an invariant variable
 to const, and then change it through the const variable (this bit seems dubious
 to me), the invariant variable has changed. But this isn't permissible. Hence,
 you can't cast invariant to const.
Ah! I'm afraid you're wrong. You /can/ cast from invariant to const - and in fact, this kind of cast is IMPLICIT. For example: invariant(char)[] s = "hello"; const(char)[] t = s; /* OK - compiles fine */ What you cannot do is "change it through the const variable". That's illegal. Absolutely illegal. In the docs, Walter says it is "undefined". Short version - never do this! char[] u = cast(char[]) s; // BAD! (The slightly longer version is you actually can do that if you really, really know what you're doing, and you've got mutex locks and such to absolutely guarantee well-defined behaviour, but it's not for the faint-hearted).
Nov 15 2007
prev sibling parent reply Regan Heath <regan netmail.co.nz> writes:
Janice Caron wrote:
 On 11/15/07, Xinok <xnknet gmail.com> wrote:
 Const is the read-only type, meaning that the data COULD change
 unexpectedly. However, invariant means the data is guaranteed never to
 change. You can't guarantee const data is never going to change,
I know that. You're stating the obvious.
 which
 is why it gives you an error.
I don't follow that reasoning. Please explain in more detail. invariant(char)[] can always be implicitly cast to const(char)[] ... and that's exactly what I'm trying to do.
Yep. You know all this already but this might be of interest to others... http://www.digitalmars.com/d/final-const-invariant.html "Implicit Conversions Mutable and invariant types can be implicitly converted to const. Mutable types cannot be implicitly converted to invariant, and vice versa. " It makes sense to allow a read-only view (const) of data which cannot change (invariant), just as it makes sense to allow a read-only view of data which can. In fact it's irrelevant whether the data can or cannot change because all const promises is that changes wont occur via the const reference itself. Returning to the problem at hand... Steven makes a good point. The AA itself is not invariant, or const. So, suppose you have: void main() { char[] bob = "bob".dup; char[] fred = "fred".dup; invariant(char)[][invariant(char)[]] iaa; const(char)[][const(char)[]] caa; iaa["hello"] = "world"; caa = iaa; //pretend this is allowed caa[bob] = fred; } Now iaa contains bob and fred which are not invariant. Regan
Nov 15 2007
parent "Janice Caron" <caron800 googlemail.com> writes:
On 11/15/07, Regan Heath <regan netmail.co.nz> wrote:
 Now iaa contains bob and fred which are not invariant.
Thank you. That makes absolutely perfect sense! Of course, now I'm going to have to think a bit harder about my code! :-)
Nov 15 2007
prev sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
"Janice Caron" wrote
I got this error...

 Error: cannot implicitly convert expression (aa) of type
 invariant(char)[][invariant(char)[]] to const(char)[][const(char)[]]

 Why not?

 Since invariant(char)[] can implicitly convert to const(char)[], I
 just don't see a problem with this.
Your first data type is an AA with invariant strings as keys and values. HOWEVER, the AA itself is not invariant. Suppose after you converted to an AA with const strings as keys and values, you replaced one of the values with a mutable string cast into a const string. I think what you might want is: const(const(char)[][const(char)[]]) This guarantees that the data will not be changed no matter what. But I'm not sure this will work either. It should, but I don't know if the compiler is smart enough to figure this out? -Steve
Nov 15 2007
parent reply "Janice Caron" <caron800 googlemail.com> writes:
On 11/15/07, Steven Schveighoffer <schveiguy yahoo.com> wrote:
 Your first data type is an AA with invariant strings as keys and values.
 HOWEVER, the AA itself is not invariant.  Suppose after you converted to an
 AA with const strings as keys and values, you replaced one of the values
 with a mutable string cast into a const string.
Yes, you're right. invariant(char)[][] won't implicitly convert to const(char)[][] either, for the same reason. But... invariant(char[])[] will implicitly conver to const(char[])[] But here's the odd thing... invariant(char[])[] will implicitly conver to const(char[])[] but invariant(char[])[int] won't implicitly convert to const(char[])[int] The only difference is the int in the square brackets.
Nov 15 2007
next sibling parent Regan Heath <regan netmail.co.nz> writes:
Janice Caron wrote:
 On 11/15/07, Steven Schveighoffer <schveiguy yahoo.com> wrote:
 Your first data type is an AA with invariant strings as keys and values.
 HOWEVER, the AA itself is not invariant.  Suppose after you converted to an
 AA with const strings as keys and values, you replaced one of the values
 with a mutable string cast into a const string.
Yes, you're right. invariant(char)[][] won't implicitly convert to const(char)[][] either, for the same reason. But... invariant(char[])[] will implicitly conver to const(char[])[] But here's the odd thing... invariant(char[])[] will implicitly conver to const(char[])[] but invariant(char[])[int] won't implicitly convert to const(char[])[int] The only difference is the int in the square brackets.
void main() { char[] fred = "fred".dup; invariant(char)[][int] iaa; const(char)[][int] caa; iaa[1] = "world"; caa = iaa; //pretend this is allowed caa[2] = fred; } Using the same reasoning :) Regan
Nov 15 2007
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
"Janice Caron" wrote
 On 11/15/07, Steven Schveighoffer <schveiguy yahoo.com> wrote:
 Your first data type is an AA with invariant strings as keys and values.
 HOWEVER, the AA itself is not invariant.  Suppose after you converted to 
 an
 AA with const strings as keys and values, you replaced one of the values
 with a mutable string cast into a const string.
Yes, you're right. invariant(char)[][] won't implicitly convert to const(char)[][] either, for the same reason. But... invariant(char[])[] will implicitly conver to const(char[])[]
Yes, this makes sense, because you then wouldn't be able to change any strings in the array, because the pointers in the strings are const.
 But here's the odd thing...

 invariant(char[])[] will implicitly conver to const(char[])[]
 but
 invariant(char[])[int] won't implicitly convert to const(char[])[int]
The only thing I can think of is that an AA does not do a copy-on-write when adding a new element as normal arrays do, so you could potentially add a member to the original AA which is not invariant. Don't know if this is why it's not allowed, or if it's even true :) -Steve
Nov 15 2007
prev sibling parent Reiner Pope <some address.com> writes:
Janice Caron wrote:
 On 11/15/07, Steven Schveighoffer <schveiguy yahoo.com> wrote:
 Your first data type is an AA with invariant strings as keys and values.
 HOWEVER, the AA itself is not invariant.  Suppose after you converted to an
 AA with const strings as keys and values, you replaced one of the values
 with a mutable string cast into a const string.
Yes, you're right. invariant(char)[][] won't implicitly convert to const(char)[][] either, for the same reason. But... invariant(char[])[] will implicitly conver to const(char[])[] But here's the odd thing... invariant(char[])[] will implicitly conver to const(char[])[] but invariant(char[])[int] won't implicitly convert to const(char[])[int] The only difference is the int in the square brackets.
I think it's just the odd behaviour that invariant(char[])[] is actually the same as invariant(char[][]), which is implicitly convertible to const(char[][]), the same as const(char[])[]. -- Reiner
Nov 15 2007