Thread overview
mutable array of immutable objects
Apr 19, 2016
Jeff Thompson
Apr 19, 2016
Anonymouse
Apr 19, 2016
Jeff Thompson
Apr 19, 2016
Timon Gehr
Apr 19, 2016
Sönke Ludwig
April 19, 2016
I want to create a mutable array of immutable objects, but the code below gives the error shown below. It seems that "new immutable(C)[1]" makes the entire array immutable, but it seems I should be able to change the elements of an array of pointers to an object even though the objects are immutable. How to do that?

class C {
  this(int x) immutable { this.x = x; }
  int x;
}

void main(string[] args)
{
  auto array = new immutable(C)[1];
  array[0] = new immutable C(10); // Error: Cannot modify immutable expression array[0].
}

April 19, 2016
On Tuesday, 19 April 2016 at 10:41:05 UTC, Jeff Thompson wrote:
> I want to create a mutable array of immutable objects, but the code below gives the error shown below. It seems that "new immutable(C)[1]" makes the entire array immutable, but it seems I should be able to change the elements of an array of pointers to an object even though the objects are immutable. How to do that?
>
> class C {
>   this(int x) immutable { this.x = x; }
>   int x;
> }
>
> void main(string[] args)
> {
>   auto array = new immutable(C)[1];
>   array[0] = new immutable C(10); // Error: Cannot modify immutable expression array[0].
> }

Mind that this is akin to declaring a string (immutable(char)[]) and trying to modify an element.

You can append, though. Or rather, make a new array/slice with the new elements concatenated into it.
April 19, 2016
On Tuesday, 19 April 2016 at 11:43:22 UTC, Anonymouse wrote:
> On Tuesday, 19 April 2016 at 10:41:05 UTC, Jeff Thompson wrote:
>> I want to create a mutable array of immutable objects, but the code below gives the error shown below. It seems that "new immutable(C)[1]" makes the entire array immutable, but it seems I should be able to change the elements of an array of pointers to an object even though the objects are immutable. How to do that?
>>
>> class C {
>>   this(int x) immutable { this.x = x; }
>>   int x;
>> }
>>
>> void main(string[] args)
>> {
>>   auto array = new immutable(C)[1];
>>   array[0] = new immutable C(10); // Error: Cannot modify immutable expression array[0].
>> }
>
> Mind that this is akin to declaring a string (immutable(char)[]) and trying to modify an element.
>
> You can append, though. Or rather, make a new array/slice with the new elements concatenated into it.

Thanks but then I'm confused as to why the following code is allowed. It is a mutable array of immutable strings. I can modify the array but not the elements they point to. What's so special about a string? Why can't I do that with my own class?

void main(string[] args)
{
  auto array = new string[1];
  array[0] = "a";
}

April 19, 2016
Am 19.04.2016 um 12:41 schrieb Jeff Thompson:
> I want to create a mutable array of immutable objects, but the code
> below gives the error shown below. It seems that "new immutable(C)[1]"
> makes the entire array immutable, but it seems I should be able to
> change the elements of an array of pointers to an object even though the
> objects are immutable. How to do that?
>
> class C {
>    this(int x) immutable { this.x = x; }
>    int x;
> }
>
> void main(string[] args)
> {
>    auto array = new immutable(C)[1];
>    array[0] = new immutable C(10); // Error: Cannot modify immutable
> expression array[0].
> }
>

Due to an omission in the type system, this requires the use of the helper type std.typecons.Rebindable:

    auto array = new Rebindable!(immutable(C))[1];
    array[0] = new immutable C(10);
April 19, 2016
On 19.04.2016 14:07, Jeff Thompson wrote:
> On Tuesday, 19 April 2016 at 11:43:22 UTC, Anonymouse wrote:
>> On Tuesday, 19 April 2016 at 10:41:05 UTC, Jeff Thompson wrote:
>>> I want to create a mutable array of immutable objects, but the code
>>> below gives the error shown below. It seems that "new
>>> immutable(C)[1]" makes the entire array immutable, but it seems I
>>> should be able to change the elements of an array of pointers to an
>>> object even though the objects are immutable. How to do that?
>>>
>>> class C {
>>>   this(int x) immutable { this.x = x; }
>>>   int x;
>>> }
>>>
>>> void main(string[] args)
>>> {
>>>   auto array = new immutable(C)[1];
>>>   array[0] = new immutable C(10); // Error: Cannot modify immutable
>>> expression array[0].
>>> }
>>
>> Mind that this is akin to declaring a string (immutable(char)[]) and
>> trying to modify an element.
>>
>> You can append, though. Or rather, make a new array/slice with the new
>> elements concatenated into it.
>
> Thanks but then I'm confused as to why the following code is allowed. It
> is a mutable array of immutable strings.

mutable array of mutable strings, actually. immutable(string)[] would be a mutable array of immutable strings.

> I can modify the array but not
> the elements they point to. What's so special about a string?

string is not a class. It is an alias for immutable(char)[].

> Why can't I do that with my own class?
> ...

D has no built-in way to express it.
There is https://dlang.org/phobos/std_typecons.html#.Rebindable.