digitalmars.D - Invariant Question (yes, another one)
- Janice Caron (6/6) Nov 15 2007 I got this error...
- Xinok (5/14) Nov 15 2007 Const is the read-only type, meaning that the data COULD change
- Janice Caron (5/10) Nov 15 2007 I don't follow that reasoning. Please explain in more detail.
- Matti Niemenmaa (8/21) Nov 15 2007 If I understood correctly:
- Janice Caron (14/19) Nov 15 2007 Ah! I'm afraid you're wrong.
- Regan Heath (25/38) Nov 15 2007 Yep. You know all this already but this might be of interest to others....
- Janice Caron (3/4) Nov 15 2007 Thank you. That makes absolutely perfect sense!
- Steven Schveighoffer (11/17) Nov 15 2007 Your first data type is an AA with invariant strings as keys and values....
- Janice Caron (11/15) Nov 15 2007 Yes, you're right.
- Regan Heath (12/32) Nov 15 2007 void main()
- Steven Schveighoffer (8/23) Nov 15 2007 Yes, this makes sense, because you then wouldn't be able to change any
- Reiner Pope (5/25) Nov 15 2007 I think it's just the odd behaviour that invariant(char[])[] is actually...
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
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
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
Janice Caron wrote:On 11/15/07, Xinok <xnknet gmail.com> 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. -- E-mail address: matti.niemenmaa+news, domain is iki (DOT) fiConst 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
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
Janice Caron wrote:On 11/15/07, Xinok <xnknet gmail.com> wrote: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. ReganConst 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
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
"Janice Caron" wroteI 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
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
Janice Caron wrote:On 11/15/07, Steven Schveighoffer <schveiguy yahoo.com> wrote: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 :) ReganYour 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
"Janice Caron" wroteOn 11/15/07, Steven Schveighoffer <schveiguy yahoo.com> wrote: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.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 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
Janice Caron wrote:On 11/15/07, Steven Schveighoffer <schveiguy yahoo.com> wrote: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[])[]. -- ReinerYour 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