const and immutable members

Daniel Davidson nospam at spam.com
Sun Sep 22 20:18:31 PDT 2013


On Sunday, 22 September 2013 at 20:17:03 UTC, Jonathan M Davis 
wrote:
> If you have
>
> struct S
> {
>     immutable int[] arr;
> }
>
> then arr can never be assigned to, so a variable of type S can 
> never be
> assigned to. But if you have

Yes - it (arr) can never be assigned to. That is the idea. It has 
already been assigned to when the data was read in, prior to 
construction of S. arr is initialized in the ctor of S.

>
> struct S
> {
>     immutable(int)[] arr;
> }
>
> then arr can be reassigned as much as you'd like, so S can be 
> assigned to.

I don't imagine wanting that in this case. I want to ensure the 
array passed at construction in is the same array being used in 
read-only fashion throughout the lifecycle of S. That is my 
intention behind using immutable. I'm saying I'll not change it 
and no one else can, other wise functions of S that might have 
made assumptions about arr could be invalidated.

> In
> both cases, the elements of the array are immutable, so it can 
> freely be a
> slice of another array and not care or affect that other array, 
> but the array
> variable itself - which only exists local to the struct - is 
> not restricted in
> being assigned to. So, you get the immutability of the data 
> without
> restricting the struct. All making arr itself immutable does 
> (rather than
> tail-immutable) is make it so that you can't reassign arr,

It also keeps the contents of arr from growing and surprising S . 
You could try to prevent with private, but still if it is a large 
module why not have the commitment not to change the contents 
(including the length), especially if it is important that you 
know the data is not changing.

> which can be useful
> sometimes, but in the case of a struct, it makes it so that the 
> whole struct
> can't be reassigned, so it's pretty much never a good idea IMHO 
> to have a
> struct with const or immutable members -

Why that conclusion? That is, why should reassignment of S take 
priority over stable data used by S? For example, take something 
like a BalanceSheetForecaster which takes a BalanceSheet as input 
in its ctor. Isn't it important that the numerous queries on and 
forecasts by the BalanceSheetForecaster be on *exactly* the same 
data?

> but having them be tail-const or
> tail-immutable still makes it so that what they refer to gets 
> all of the
> benefits of const or immutable without restricting the struct.
>

I appreciate the explanation and think I understand the benefit 
of tail-const better. You would not easily be able to store 
modifiable collections of BalanceSheetForecasters, unless you did 
it with pointers. But the focus of the discussion seems to be on 
immutable(T)[] which is my fault for choosing the first and 
easiest type of aliasing I could in my example. I think the slice 
is really a special case when it comes to aliasing. With 
immutable(T)[] you have the benefit of not having to worry about 
aliasing because of the way it is implemented - the contiguous 
nature and copy on write semantics. But this is not the general 
case is it? For example, do the same arguments hold for 
associative arrays?

struct S {
   immutable string[string] aarr;
}

Doesn't using immutable there present the same problem as with 
the slice? S is no longer assignable. But who would recommend not 
using immutable in this case if you want aarr to be stable. If 
you do not use immutable then who knows when your array will grow 
without your expecting it? At least with the slice your memory 
safety is in the control of your module if you make it private. 
But with associative array it would depend entirely on client 
code providing the data still having a handle on it.


More information about the Digitalmars-d-learn mailing list