Inability to dup/~ for const arrays of class objects

Peter Williams pwil3058 at bigpond.net.au
Tue May 28 20:43:49 PDT 2013


On 29/05/13 11:31, Steven Schveighoffer wrote:
>
>> I'm implementing sets and the concept is sets of objects not sets of
>> the values in the objects.  I want to be able to initialize sets using
>> arrays and I'm promising that I won't change the array or its
>> contents.   I'm also trying to promise that I won't (inside the set
>> implementation) make any changes to individual objects.  But I'm not
>> promising that they won't be changed by other code that has access to
>> them.  The invariant (I wrote) for the sets implies that any changes
>> made by that code can't change the sort order of the objects.
>
> Then you are trying to make a *momentary* guarantee.

Almost.  I'm also saying I won't change it any time within the set.

>
> In essence, you want to transform the array into a set, but still
> guarantee that the underlying data hasn't changed.

More or less. The set code won't change it something else might.

>
> This is very difficult to express with the type system.

I'm starting to realize this :-)

I've always been frustrated in other languages by const (and friends) 
being inadequate for saying what I want to say.

> The closest you
> can get is inout, which *might* be able to do it.
>
> For example:
>
> inout(T)[] copyIt(T)(inout(T)[] arr)
> {
>     // this is quirky, but it's the easiest way to do it without an
> equivalent .dup for inout
>     inout(T)[] result;
>     result ~= arr;
>     return result;
> }
>
> Now, if you pass in mutable, you get mutable.  If you pass in const, you
> get const.  If you pass in immutable, you get immutable.
>
> I say *might* because I don't know what your code is doing, or how your
> set type actually looks.  It may be logical, but impossible to currently
> express.  inout still has some room for improvement (and so does the
> whole const system in general).
>
>> No, I really don't want copies although I can see that might have it's
>> uses in another application.  It's the mathematical concept of sets
>> that I'm trying for not just containers.  I.e. it's a way of selecting
>> groups of objects, combining groups without duplicates, etc.
>
> Another option is to simply define your types as "immutable" types.
> That is, specify the data inside is immutable, but the class itself is not.

No.  I need to be able to make changes to the objects (that doesn't 
effect their order).  It's kind of like an associative array (which I 
did consider as a mechanism for doing what I wanted) but without 
splitting the object into a key/value pair.

One place I'm using it is for managing symbols (look ahead sets, etc) in 
a parser generator.  The symbols' permanent home is in an associative 
array indexed by their name (which is also included in the symbol 
object) but they may belong to many look ahead sets.  Usually, 
processing that requires access to attributes of the symbol (other than 
the key) occurs when processing one of the look ahead sets and going 
looking for the symbol table looking for the data is an unnecessary 
complication (not to mention an efficiency hit).  Having exactly one 
object per symbol but still being able to have it multiple sets is a big 
efficiency gain especially when it comes to making changes to the 
ancillary data as you only have to change it in one place.

>
> e.g.:
>
> class C
> {
>     immutable int c;
>     this(int x) { c = x;}
> }
>
> You are hitting a very common pain-point for const/immutable, for which
> there is really not a good answer currently.

I agree.

This happens every time I try a new language.  I get all excited about 
making my code bulletproof only to be mugged by reality. :-)  In the 
end, it comes down to coding carefully.

Peter



More information about the Digitalmars-d mailing list