questions around mutating range algorithms, const, and return ref

aliak something at something.com
Tue Jan 30 08:17:01 UTC 2018


On Monday, 29 January 2018 at 12:10:16 UTC, Simen Kjærås wrote:
>
> Consider this case:
>
> immutable(int)[] a = [1,2,3];
> immutable(int)* b = &a[1];
>
> You're free to slice the array or pop elements off its front or 
> back, but if you change the order of elements, the value that b 
> points to will change. D does not allow this.
>
> You can create a new array with the elements moved into the 
> locations you want, and with another layer of indirections 
> (int*[]) you can move the elements of the array without 
> mutating the values.

Ooh my... yes I can understand that. And I guess immutable is 
implicitly convertible to const and then if you can move const 
stuff then you have that problem. From the FAQ, my general 
understanding is that const is there as a bridge from immutable 
to mutable as a promise that the memory under this symbol will 
not be altered by that reference.

While experimenting a bit I came across this though which, 
currently, I do understand that value of

struct Int {
     const int value;
}

void main() {
     Int i0 = Int(0);
     Int i1 = Int(1);
     Int i2 = Int(2);
     Int[3] arr0 = [i0, i1, i2];
     Int[] arr1;
     arr1 ~= i0;
     arr1 ~= i1;
     arr1 ~= i2;

     arr1[0] = i0; // nope, Error: cannot modify struct arr1[0] 
Int with immutable members
}

So if a struct has a struct that has any member const, then 
effectively that whole struct is a const (well immutable it 
seems, so not even const)? Is that really correct? What is this 
sorcery? If yes I find it very surprising, but I don't think I'm 
very clear on what D is trying to solve with const ... yet.

I find const a little hard to swallow so far. From what I 
understand, it's good for function parameters, and as a function 
attribute for functions that return temporaries, except don't use 
it with ranges (i.e. don't put it on front). Actually not sure 
about function attributes on second thought. So... function 
parameters and local variables that you know won't change is what 
I'm going to go with for now.

>
>> Also hasMobileElements!(const int[]) is true, so that means I 
>> can move elements around right?
>
> hasMobileElements checks if the value of front can be moved as 
> in move constructors, not as in 'can be moved to a different 
> spot in the range'. I will admit the name does little to 
> unconfuse this point.

I'm not following here :s If value of front can be move 
constructed, then something can take it's place no?

Thank you!




More information about the Digitalmars-d-learn mailing list