string types: const(char)[] and cstring

Derek Parnell derek at psych.ward
Sun May 27 04:30:06 PDT 2007


On Sun, 27 May 2007 01:09:40 -0700, Walter Bright wrote:

Thanks for taking the time out to help me understand the proposed D
changes. I really appreciate it.

I think that I'm going to have to wait until you have an implementation to
try it on; to see how it fits with my terminology and needs.

> Derek Parnell wrote:
>> You said "strings should be immutable" and I saying that seems odd because
>> my experience is that most strings are meant to be changed. 
> 
> I'm going to argue that your experience is unusual. I do a lot of string 
> manipulation (after all, that's what a compiler does) and the strings, 
> once constructed, are essentially always immutable. In conversations 
> with many others, my experience is commonplace.

Ok we'll leave it that then. However the phrase "once constructed" is the
key one I suspect. Its like saying, once I've finished changing things I
don't want them to change anymore - no argument there. So the idea would be
to work with mutable strings until they are finished being constructed and
then cast them to immutable for the rest of the run time. I'm thinking here
of things like changing case, macro expansion, standarizing file names,
constructing message text, etc ...

> But still, in D, nothing prevents you from using mutable strings.

That's why I can see that I'll be continuing to use 'alias char[] string',
unless you make 'string' the immutable beastie of course <g>

>>>> So 'const(char)[] x' means that I can change x.ptr and x.length but I
>>>> cannot change anything that x.ptr points to, right?
>>> Right.
>>>
>>>> And  'invariant(char)[] x' means that I cannot change x.ptr or x.length and
>>>> I cannot change anything that x.ptr points to, right?
>>> Wrong. The difference between const and invariant is that invariant is 
>>> truly, absolutely, immutable. 
>> 
>> Huh??? Isn't that what I just said?
> 
> No. You said for const you could change x.ptr and x.length, but for 
> invariant you could not. For both const and invariant, you can change 
> x.ptr and x.length.

See, this is what is weird ... I can have an invariant string which can be
changed, thus making it not really invariant in the English language sense.
I'm still thinking that "invariant" means "does not change ever". 

But it seems that I'm wrong ...

 invariant char[] x; 
 x = "abc".dup;  // The string 'x' now contains "abc";
 x = "def".dup;  // The string (which is not supposed to change
                 // i.e invariant) has been changed to "def".

Now this is counter-intuitive (read: *WEIRD*), no?

>> Now I'm even more confused about these
>> terms. They are just not intuitive, are they?
> 
> The problem is I have failed to explain them. Invariant data can go into 
> read-only memory. Const data can be changed by another reference to the 
> same data (just like in C++). In other words, const is a read-only 
> *view* of the data, whereas invariant data is read-only for all views of it.

Okay, I've got that now ... but how to remember that two terms that mean
the same in English actually mean different things in D <G>

I think I read that someone suggested that 'const' be a contraction of
'constrained' rather than 'constant' - that might help. And that
'invariant' is longer than 'const' so its effect is 'bigger'.

  invariant char[] x; // The data pointed to by 'x' cannot be changed
                      // by anything anytime during the execution
                      // of the program.
                      // (So how do I populate it then? Hmmmm ...)

  const char[] y;    // The data pointed to by 'y' cannot be changed
                     // by anything anytime during the execution
                     // of the program when using the 'y' variable,
                     // however using another variable that also
                     // refers to y's data, or some of it, is ok.

For example ...

  void func (const char[] a, char[] b)
  {
        a[0] = 'a'; // fails
        b[0] = 'a'; // succeeds
  }

  char[] y = "def".dup;
  func( y, y);
  
>> I'm sorry I'm a bit slow on this ... but what is the difference between
>> "invariant" and "const final" ? Is it that "invariant" is sort of a global
>> effect but "const final" is only in effect for the specific reference it
>> occurs on.
> 
> First differences: final is a *storage class*. const and invariant are 
> *type constructors*.

Thanks. So 'final' means that it can be changed (from its initial default
value) once and only once.

/* --- Scenario #1 --- */
  final int r;
  r = randomer(); // succeeds
  foo(); // fails 

  int randomer() { 
      // Get a random integer between -100 and 100.
      return cast(int)(std.random.rand() % 201) - 100; 
  }
  void foo() { 
    r = randomer(); // success depends on whether or not 'r' 
                    // has already been set.
  }


/* --- Scenario #2 --- */
  final int r;

  foo(); // succeeds
  r = randomer(); // fails

  int randomer() { 
      // Get a random integer between -100 and 100.
      return cast(int)(std.random.rand() % 201) - 100; 
  }
  void foo() { 
    r = randomer(); // success depends on whether or not 'r' 
                    // has already been set.
  }

Is this a run-time check or a compile time one? If run-time, would it be
possible to somehow 'unfinal' a variable using some implementation
dependant trickery.

>> I'm not looking forward to reading the docs on this. I hope you get a lot
>> of people to edit the docs to make it understandable for everyone.
> 
> The thing is actually rather simple, but I am having trouble finding the 
> right words to express it. 

And thus my comment re editors.

> Certainly, the mishmash of C++ const has 
> badly muddied the waters about what const means.

I have no real knowledge of C++ or its const, and I'm still weirded out by
it all <G>

-- 
Derek Parnell
Melbourne, Australia
"Justice for David Hicks!"
skype: derek.j.parnell



More information about the Digitalmars-d-announce mailing list