Re: Associative Array of Const Objects?
On Sun, 29 Mar 2015 20:29:49 +, 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. signature.asc Description: PGP signature
Re: Associative Array of Const Objects?
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
Re: Associative Array of Const Objects?
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
Re: Associative Array of Const Objects?
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
Re: Associative Array of Const Objects?
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 */ 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`. 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-only
Re: Associative Array of Const Objects?
Although, I suppose this is still a step up from C# which has not const at all =O
Re: Associative Array of Const Objects?
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-only I 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.
Re: Associative Array of Const Objects?
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 it 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. 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.
Re: Associative Array of Const Objects?
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`.
Re: Associative Array of Const Objects?
On Sunday, 29 March 2015 at 20:29:50 UTC, bitwise wrote: 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. `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. 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. 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.
Re: Associative Array of Const Objects?
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
Re: Associative Array of Const Objects?
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.
Re: Associative Array of Const Objects?
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.
Associative Array of Const Objects?
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?