Extended Type Design: further examples

Derek Parnell derek at nomail.afraid.org
Mon Mar 19 17:14:40 PDT 2007


On Mon, 19 Mar 2007 16:20:04 -0700, Andrei Alexandrescu (See Website For
Email) wrote:

> Derek Parnell wrote:
>> I wish it wasn't so hard to get a simple straight answer from the experts.
> 
> It's not like anybody tries to obfuscate their writing.

LOL ... I realize that. Some people are just naturals at it.

>> So far I think /The W&A Show/ is saying that 'const' and 'invariant' only
>> apply to reference data types (objects, variable-length arrays, and
>> pointers) and structs. They do not apply *in any way, shape or form* to any
>> other data type.
>> 
>>   const char[] s;    // ok
>>   const char   c;    // meaningless, the 'const' is ignored.
>>   const classFoo f;  // okay
>>   const double* b;   // okay;
>>   const double  d;   // meaningless, the 'const' is ignored.
>>   const structBar q; // okay
>> 
>> 'const' means you cannot change the stuff the reference is referencing or
>> the members of the struct, *but* for reference types you can change the
>> reference value.
>> 
>>   s[0] = 'a'; // fails
>>   s    = "new data"; //ok
>>   s.length = 2; // ok
>> 
>>   c    = 'a'; // ok
>> 
>>   f.bar = 'a'; // fails
>>   f = new classFoo(); // okay
>> 
>>   *b    = 1.0; // fails
>>   b     = &someDouble; // ok
>> 
>>   d     = 1.0; // okay
>> 
>>   q.foo = 'a'; // fails
> 
> Correct.


YAY!!!! Finally something has sunk in to my head <G>
 
>> 'invariant' means you cannot change the stuff the reference is referencing
>> or the members of the struct, *and* for reference types you cannot change
>> the reference value.
> 
> No. Invariant means that the data referenced indirectly is never 
> modifiable by any part of the program.
> 
> What you called 'invariant' above is 'final const'.

Hmmm ... so the difference between 'const' and 'invariant' is that const is
only effective for one level deep, but 'invariant' is effective for all
levels, right?

  struct Foo
  {
      int a;
      int* b;
      Foo c;
      Foo* d;
  }

  const Foo f_const;
  invariant Foo f_invar;
  int x;

  // assuming we can initialize f_const and f_invar at run time somehow,
  // then are the following subsequent assignments as stated?
  f_const.a = 1;       // fails
  f_const.b = &x;      // fails
  *f_const.b = 1;      // okay;
  f_const.c.a = 1;     // okay
  f_const.c.b = &x;    // okay
  *f_const.c.b = 1;    // okay
  f_const.d = new Foo; // fails
  f_const.d.a = 1;     // okay
  f_const.d.b = &x;    // okay
  *f_const.d.b = 1;    // okay

  f_invar.a = 1;       // fails
  f_invar.b = &x;      // fails
  *f_invar.b = 1;      // fails;
  f_invar.c.a = 1;     // fails
  f_invar.c.b = &x;    // fails
  *f_invar.c.b = 1;    // fails
  f_invar.d = new Foo; // fails
  f_invar.d.a = 1;     // fails
  f_invar.d.b = &x;    // fails
  *f_invar.d.b = 1;    // fails


> [snip]
>> However, if this is the interpretation of 'invariant', how does one ever
>> get to set the 'invariant' thing's value?
>> 
>>    invariant byte[] vCodes;
>>    . . . 
>>    vCodes = LoadCodesFromFile();  // fails, no???
> 
> Right now you can only initialize invariant with literals. This aspect 
> of the language is still under development. (Things like the result of 
> some_string.dup also come to mind.)

Oh ... okay. I'll wait for that mind bender then.

>>  void func( string s )
>>  {
>>      char[] u;
>>      u = s;
> 
> You can't make the assignment u = s.

Oh, okay. The compiler will stop at "u = s;" because that would have made
access to 's' data via the 'u' symbol. Got it.
 
>>> 3. The ~= operator works (somewhat surprisingly).
>>  void func( string s )
>>  {
>>      string t;
>>      char[] u;
>> 
>>      u ~= s; // ok
>>      s ~= 'a'; // fails ???
>> 
>>      t ~= s; // fails???
>>  }
> 
> s ~= a; works and is equivalent to s = s ~ a, i.e. "rebind s to the 
> concatenation of s and a". It's an operation that does not mutate s's 
> contents.

So, could this be the mechanism to set an invariant array?

   invariant ubyte[] b;
   b ~= Load_Stuff_From_File();

>>> 4. It's very, very rare that you want to modify some random character in
>>> a string, and when you do, use a char[] and then copy it back into a
>>> string, or rebuild the string from slices!
>> 
>> It is not so rare in the type of applications that I do. 
> 
> You use char[] for that, and when you are done modifying, you can put 
> things in a string.

Oops. I was using "string" in the normal sense and not your new alias idea.
In the context of the alias 'string' then what you say makes a lot of
sense.

> It's like watching TV: you can always change your choice of watching

(Not if my wife has the remote <G>)

-- 
Derek
(skype: derek.j.parnell)
Melbourne, Australia
"Justice for David Hicks!"
20/03/2007 10:53:00 AM



More information about the Digitalmars-d mailing list