digitalmars.D.learn - Associative Array of Const Objects?
- bitwise (11/11) Mar 27 2015 class Test{}
- bearophile (7/18) Mar 28 2015 You meant to say "associative array with const objects as
- bitwise (15/16) Mar 29 2015 Looking at Rebindable now, there is a useful example. There
- "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> (7/18) Mar 28 2015 FWIW, it was changed in
- bitwise (14/14) Mar 29 2015 I'm a little confused at this point why this doesn't work either:
- bearophile (6/8) Mar 29 2015 const and immutable are rather different between C++ and D, I
- anonymous (19/34) Mar 29 2015 Notice how you have that '*' there that allows you to distinguish
- Baz (24/35) Mar 28 2015 Generally speaking, you can insert an item in a constructor:
class Test{} void main() { const(Test)[string] tests; tests["test"] = new Test(); } This code used to work, but after upgrading to dmd 2.067, it no longer does. --Error: cannot modify const expression tests["test"] How do I insert an item into an associative array of const objects?
Mar 27 2015
bitwise:class Test{} void main() { const(Test)[string] tests; tests["test"] = new Test(); } This code used to work, but after upgrading to dmd 2.067, it no longer does. --Error: cannot modify const expression tests["test"] How do I insert an item into an associative array of const objects?You meant to say "associative array with const objects as values". I think the short answer is that you can't. This is a breaking change, I think, it broke some of my code too. But perhaps something like Rebindable could be used. Bye, bearophile
Mar 28 2015
perhaps something like Rebindable could be used.Looking at Rebindable now, there is a useful example. There should probably be a mention of this on the const/immutable docs. For people coming from C++, this will not be obvious. auto a = Rebindable!(const Widget)(new Widget); a.y(); // fine a.x = 5; // error! can't modify const a a = new Widget; // fine Given the above example though, I have to say it's ridiculously verbose and I much prefer the C++ way. I have never used read-only-const in C++, nor would I, and it's really annoying that it's forced on D programmers. I can see the benefit of protecting the underlaying data, but not the pointer/reference itself. I'm assuming a DIP for this would be futile at best =/ Thanks
Mar 29 2015
On Friday, 27 March 2015 at 21:33:19 UTC, bitwise wrote:class Test{} void main() { const(Test)[string] tests; tests["test"] = new Test(); } This code used to work, but after upgrading to dmd 2.067, it no longer does. --Error: cannot modify const expression tests["test"] How do I insert an item into an associative array of const objects?FWIW, it was changed in https://github.com/D-Programming-Language/dmd/pull/4148 It seems Kenji argues that the first assignment (like in your case) should be allowed, because it's supposed to be a construction rather than an assignment, but I fail to see how the compiler could detect this in the general case.
Mar 28 2015
I'm a little confused at this point why this doesn't work either: const(Test) test = new Test(); // fine test = new Test(); // error In C++, There is a clear distinction: const Test *test1 = nullptr; // const before type test1 = new Test(); // fine Test *const test2 = nullptr; // const before identifier test2 = new Test(); // error: test2 is readonly Isn't there such a distinction in D? I would have suggested that I got things backward, but this doesn't work either: const Test test = new Test(); test = new Test(); // error: cannot modify const expression
Mar 29 2015
bitwise:I'm a little confused at this point why this doesn't work either:const and immutable are rather different between C++ and D, I suggest you to take a look at the documentation: http://dlang.org/const-faq.html Bye, bearophile
Mar 29 2015
On Sunday, 29 March 2015 at 18:43:32 UTC, bitwise wrote:I'm a little confused at this point why this doesn't work either: const(Test) test = new Test(); // fine test = new Test(); // error In C++, There is a clear distinction: const Test *test1 = nullptr; // const before type test1 = new Test(); // fine Test *const test2 = nullptr; // const before identifier test2 = new Test(); // error: test2 is readonly Isn't there such a distinction in D?Notice how you have that '*' there that allows you to distinguish the data from the reference. You can have a mutable pointer to const data in D, too: struct Test {} const(Test)* test1 = null; test1 = new Test; /* fine */ const(Test*) test2 = null; /* equivalent variant: const Test* test2 = null; */ test2 = new Test; /* Error: cannot modify const expression test2 */ You cannot have a mutable class object reference to const data, because syntactically that distinction isn't made in D. There is std.typecons.Rebindable, though: import std.typecons: Rebindable; class Test {} Rebindable!(const Test) test = null; test = new Test; /* fine */I would have suggested that I got things backward, but this doesn't work either: const Test test = new Test(); test = new Test(); // error: cannot modify const expression`const Test test` is the same as `const(Test) test`.
Mar 29 2015
On Sunday, 29 March 2015 at 19:04:30 UTC, anonymous wrote:Notice how you have that '*' there that allows you to distinguish the data from the reference. You can have a mutable pointer to const data in D, too: struct Test {} const(Test)* test1 = null; test1 = new Test; /* fine */ const(Test*) test2 = null; /* equivalent variant: const Test* test2 = null; */ test2 = new Test; /* Error: cannot modify const expression test2 */ You cannot have a mutable class object reference to const data, because syntactically that distinction isn't made in D. There is std.typecons.Rebindable, though: import std.typecons: Rebindable; class Test {} Rebindable!(const Test) test = null; test = new Test; /* fine */Interesting, but I still don't understand why D doesn't have something like this: const Test test; // or const(Test) test; test = new Test() // fine, underlaying data is const, the reference is not Test const test = new Test(); test.a = 5; // fine, test is read-only but underlaying data is not const test = new Test(); // error: test is read-only const(Test) const test = new Test(); test.a = 5; // error, underlaying data is const test = new Test(); // error: read-onlyI would have suggested that I got things backward, but this doesn't work either: const Test test = new Test(); test = new Test(); // error: cannot modify const expression`const Test test` is the same as `const(Test) test`.
Mar 29 2015
On Sunday, 29 March 2015 at 19:13:32 UTC, bitwise wrote:Interesting, but I still don't understand why D doesn't have something like this: const Test test; // or const(Test) test; test = new Test() // fine, underlaying data is const, the reference is not Test const test = new Test(); test.a = 5; // fine, test is read-only but underlaying data is not const test = new Test(); // error: test is read-only const(Test) const test = new Test(); test.a = 5; // error, underlaying data is const test = new Test(); // error: read-onlyI think the semantics you propose here are not good. The first example would change the meaning of existing syntax (bad). The second one shows a const reference to mutable data (head const), which is a no-go for D so far. Shuffling things around, this could be less disruptive addition to the language: Test const test; /* mutable reference to const data */ But: 1) Such placement based syntax is foreign to D. 2) It would be special syntax just for class types. 3) It's not how C++ rolls. `const Test test;` and `Test const test;` are equivalent in C++. You need that '*' in C++, too, to make a distinction between reference and data. 4) Rebindable works reasonably well, as far as I know. So there is not that much pressure to change the language.
Mar 29 2015
1) Such placement based syntax is foreign to D.I would have to agree that this is a strange way to do things in any language. The great "int* a" vs "int *a" debate...2) It would be special syntax just for class types.IMO, it would be worth it3) It's not how C++ rolls. `const Test test;` and `Test const test;` are equivalent in C++. You need that '*' in C++, too, to make a distinction between reference and data.I'm a little confused. I was comparing a C++ pointer-to-class to a D reference, which are basically the same under the hood. I wasn't trying to bring up C++ value types. I'm not sure how they're relevant to the argument.4) Rebindable works reasonably well, as far as I know.The verbosity and blatant disregard for DRY makes me CRY. See what I did there.. ;) Anyways, IMO, D could benefit from having "tailconst" but I think it's a moot point.
Mar 29 2015
On Sunday, 29 March 2015 at 20:29:50 UTC, bitwise wrote:`Test` can be a pointer type: class C {}; typedef C *Test; const Test test1 = 0; Test const test2 = 0; /* same type as test1 */ The point is that C++ shares the problem: If all you have is one identifier (and no pointer star), you can't distinguish the data from the pointer. So C++ syntax could only be properly adopted into D, if D class references got something like the pointer star. At that point, current D syntax with parentheses would work, too.3) It's not how C++ rolls. `const Test test;` and `Test const test;` are equivalent in C++. You need that '*' in C++, too, to make a distinction between reference and data.I'm a little confused. I was comparing a C++ pointer-to-class to a D reference, which are basically the same under the hood. I wasn't trying to bring up C++ value types. I'm not sure how they're relevant to the argument.Yeah, I don't like Rebindable very much either. But it works ok, so whatever. If you have strong arguments, maybe post to the general forum. For me it's just about aesthetics.4) Rebindable works reasonably well, as far as I know.The verbosity and blatant disregard for DRY makes me CRY. See what I did there.. ;) Anyways, IMO, D could benefit from having "tailconst" but I think it's a moot point.
Mar 29 2015
On Sun, 29 Mar 2015 20:29:49 +0000, bitwise wrote:The verbosity and blatant disregard for DRY makes me CRY. See what I did there.. ;)you can always `alias` it to something funny or obscene.=
Mar 29 2015
On Friday, 27 March 2015 at 21:33:19 UTC, bitwise wrote:class Test{} void main() { const(Test)[string] tests; tests["test"] = new Test(); } This code used to work, but after upgrading to dmd 2.067, it no longer does. --Error: cannot modify const expression tests["test"] How do I insert an item into an associative array of const objects?Generally speaking, you can insert an item in a constructor: --- class Test{} const (Test)[string] tests; static this() { tests["test"] = new Test(); } class Bar { immutable (Test)[string] tests2; this() { this.tests2["test"] = new Test(); } } void main() { auto bar = new Bar; } --- The same problem already existed before 2.067 for AA with strings as value (string[string]), since they are immutable.
Mar 28 2015