Jump to page: 1 2
Thread overview
Associative Array of Const Objects?
Mar 27, 2015
bitwise
Mar 28, 2015
bearophile
Mar 29, 2015
bitwise
Mar 28, 2015
Marc Schütz
Mar 29, 2015
bitwise
Mar 29, 2015
bearophile
Mar 29, 2015
anonymous
Mar 29, 2015
bitwise
Mar 29, 2015
bitwise
Mar 29, 2015
anonymous
Mar 29, 2015
bitwise
Mar 29, 2015
anonymous
Mar 30, 2015
ketmar
Mar 28, 2015
Baz
March 27, 2015
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?
March 28, 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
March 28, 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.
March 28, 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.
March 29, 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
March 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
March 29, 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
March 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`.
March 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 */
>
>> 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

March 29, 2015
Although, I suppose this is still a step up from C# which has not const at all =O
« First   ‹ Prev
1 2