May 27, 2007
renoX Wrote:
> I agree with you, I don't think that the string should be a char[] alias, wether it's const or not but a class with char[],dchar[],wchar[] under the hood representation and safe slicing by default.
> 
> The difficulty is providing enough flexibility for managing correctly the internal representation: there should be a possibility to say use UTF8 even though there are multibyte characters for example (a size optimization with some CPU cost).

I think the class you describe would be useful, but only for certain types of application.  Many applications (those that deal with ASCII or only one of UTF8, 16 or 32 for example) wont need the sorts of things this class provides and can get away with just using 'const(char[])' AKA 'string'.  Basically I think there is a ample room for both 'string' as an alias and 'String' as a class to exist at the same time.

Regan
May 27, 2007
Derek Parnell wrote:
> 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". 

Where you're going wrong is that there are two parts to a dynamic array - the contents of the array, and the ptr/length values of the array.

	invariant(char)[]

immutalizes (look ma! I coined a new word!) only the contents of the array.

	invariant(char[])

immutalizes the contents and the ptr/length values.


> 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?

The first issue is that you've confused:
	invariant char[] x;
with:
	invariant(char)[] x;

Remember, there are TWO parts to an array, and the invariantness can be controlled for either independently, or both. This isn't different from in C++ there are two parts to a char*, the char part, and the pointer part.

> 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>

English is imprecise and ambiguous, that's why we have mathematical languages, and programming languages.

>   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 ...)

You can't populate an invariant(char)[] array (which is what you meant, not invariant char[]). The way to get one is to cast an existing array to invariant.

>   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.

Yes, but here again, const(char)[].

> For example ...
> 
>   void func (const char[] a, char[] b)
>   {
>         a[0] = 'a'; // fails
>         b[0] = 'a'; // succeeds
>   }
> 
>   char[] y = "def".dup;
>   func( y, y);

Yup, that's the aliasing issue with const.


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

No. 'final' means it is set only at initialization.

> /* --- Scenario #1 --- */
>   final int r;
>   r = randomer(); // succeeds
Nope, this fails. Try:
	final int r = randomer();
>   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.
No, this assignment always fails.
>   }
> 

> Is this a run-time check or a compile time one?

Compile time.

> If run-time, would it be
> possible to somehow 'unfinal' a variable using some implementation
> dependant trickery.

Yes, but the result is undefined behavior. Just like if you went around the typing system and converted an int into a pointer, and tried to access data with it. You can do it, but you're on your own with that.


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

I'm beginning to realize that unless one understands how types are represented at run time, one will never understand const.
May 27, 2007
Anders F Björklund wrote:
> When using Java (and Objective-C), I've found it very useful that strings (and others) are immutable since they are then thread-safe.

Being able to treat strings as value types is where the big simplification (in user code) comes, and invariant strings should do that.
May 27, 2007
Derek Parnell wrote:
>  const(char)[]  // A mutable array of immutable characters?
>  const(char[])  // An immutable array of mutable characters?
>  const(const(char)[]) // An immutable array of immutable characters?
>  char[]         // A mutable array of mutable characters?
> 
> What will happen with the .reverse and .sort array properties when used
> with const, invariant, and final qualifiers?

They'll all fail.
May 27, 2007
Regan Heath a écrit :
> renoX Wrote:
>> I agree with you, I don't think that the string should be a char[]
>>  alias, wether it's const or not but a class with
>> char[],dchar[],wchar[] under the hood representation and safe
>> slicing by default.
>> 
>> The difficulty is providing enough flexibility for managing
>> correctly the internal representation: there should be a
>> possibility to say use UTF8 even though there are multibyte
>> characters for example (a size optimization with some CPU cost).
> 
> I think the class you describe would be useful, but only for certain
> types of application.  Many applications (those that deal with ASCII

Hopefully a rare thing now.

> or only one of UTF8, 16 or 32 for example)

Sure, but this makes the code less portable (or less efficient when it's not on its "original" OS): Windows use UTF16, Linux UTF8..

> wont need the sorts of
> things this class provides and can get away with just using
> 'const(char[])' AKA 'string'.  Basically I think there is a ample
> room for both 'string' as an alias and 'String' as a class to exist
> at the same time.

Room of course, but IMHO one should almost always use the class (except in wrappers of native calls) instead of the alias.

renoX

> 
> Regan
May 27, 2007
On Sun, 27 May 2007 12:14:29 -0700, Walter Bright wrote:

> Derek Parnell wrote:
>>  const(char)[]  // A mutable array of immutable characters?
>>  const(char[])  // An immutable array of mutable characters?
>>  const(const(char)[]) // An immutable array of immutable characters?
>>  char[]         // A mutable array of mutable characters?


Any comment on the above?


>> What will happen with the .reverse and .sort array properties when used with const, invariant, and final qualifiers?
> 
> They'll all fail.

Good, but when? At run time or compile time?

-- 
Derek Parnell
Melbourne, Australia
"Justice for David Hicks!"
skype: derek.j.parnell
May 27, 2007
Derek Parnell wrote:
> On Sun, 27 May 2007 12:14:29 -0700, Walter Bright wrote:
> 
>> Derek Parnell wrote:
>>>  const(char)[]  // A mutable array of immutable characters?
>>>  const(char[])  // An immutable array of mutable characters?
>>>  const(const(char)[]) // An immutable array of immutable characters?
>>>  char[]         // A mutable array of mutable characters?
> 
> 
> Any comment on the above?

Looks right to me.

>>> What will happen with the .reverse and .sort array properties when used
>>> with const, invariant, and final qualifiers?
>> They'll all fail.
> 
> Good, but when? At run time or compile time?

compile time.
May 27, 2007
On Sun, 27 May 2007 12:06:06 -0700, Walter Bright wrote:

> Derek Parnell wrote:
>> 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".
> 
> Where you're going wrong is that there are two parts to a dynamic array - the contents of the array, and the ptr/length values of the array.
>
> 	invariant(char)[]
> 
> immutalizes (look ma! I coined a new word!) only the contents of the array.
> 
> 	invariant(char[])
> 
> immutalizes the contents and the ptr/length values.

I know that you know that I know this about arrays already (did I really just say that!?) so I assume you are talking to the greater audience that we have here.

So to immutalize (see it must be a real word as someone else is using it<g>) just the ptr/length parts I'd use ...

  invariant char([])   ?????
  char invariant[]     ????

and

  invariant char[]

is the same as

  invariant (char[])

right?


>> 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?

In my thinking the term 'string' refers to the whole ptr/length/content
group. So when one says that a string is immutable I'm thinking they are
saying that every aspect of the string does not change. This is where I
suspect that we are having terminology problems.

> The first issue is that you've confused:
> 	invariant char[] x;
> with:
> 	invariant(char)[] x;

Yep - guilty as charged, your honour. Actually it is not so much confusion rather just a poor typing regime, as I really did understand the difference but I typed in the wrong thing. But let's continue ...

> Remember, there are TWO parts to an array, and the invariantness can be controlled for either independently, or both. This isn't different from in C++ there are two parts to a char*, the char part, and the pointer part.

What is the syntax for controlling *just* the reference part of an array?

>> 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>
> 
> English is imprecise and ambiguous, that's why we have mathematical languages, and programming languages.

Has anyone got a dictionary in which "constant" and "invariant" are not synonyms? Sure I agree that "English is imprecise and ambiguous" when taken as a whole but not every word is such. So when one uses English words in a programming language the natural thing is to assume that the programming language meaning has a high degree of correlation with the English meaning.


>>   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 ...)
> 
> You can't populate an invariant(char)[] array (which is what you meant, not invariant char[]). The way to get one is to cast an existing array to invariant.

  char[] name;
  name = GetUserName();

  invariant (char)[] newb = cast(invariant)name;

  void foo() { name[0] = toUpperCase(name[0]); }  // Is this valid?

  foo(); // What about this?

>>   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.
> 
> Yes, but here again, const(char)[].

Yeah yeah yeah ... I can see how an alias is going to be a boon.


>> Thanks. So 'final' means that it can be changed (from its initial default
>> value) once and only once.
> 
> No. 'final' means it is set only at initialization.

And initialization means "on the same statement that declares the variable"?

In English, initialization means whenever some thing is initialized rather than one specific type of initialization.


>> /* --- Scenario #1 --- */
>>   final int r;

Ok, so the above "initializes" the symbol to zero, being the default value of an int, and it cannot be changed to anything else now.

>>   r = randomer(); // succeeds
> Nope, this fails. Try:
> 	final int r = randomer();

Got it.

>> I have no real knowledge of C++ or its const, and I'm still weirded out by it all <G>
> 
> I'm beginning to realize that unless one understands how types are represented at run time, one will never understand const.

Nah, it's probably just me that's being thick, ... and I *do* understand the run-time implementation of the D constructs.

-- 
Derek Parnell
Melbourne, Australia
"Justice for David Hicks!"
skype: derek.j.parnell
May 27, 2007
On Sun, 27 May 2007 16:32:57 -0700, Walter Bright wrote:

> Derek Parnell wrote:
>> On Sun, 27 May 2007 12:14:29 -0700, Walter Bright wrote:
>> 
>>> Derek Parnell wrote:
>>>>  const(char)[]  // A mutable array of immutable characters?
>>>>  const(char[])  // An immutable array of mutable characters?
>>>>  const(const(char)[]) // An immutable array of immutable characters?
>>>>  char[]         // A mutable array of mutable characters?
>> 
>> 
>> Any comment on the above?
> 
> Looks right to me.

But didn't you say that "invariant char[]" means that "invariant" applies to both the array reference and the contents? In other words its the same as "invariant (char[])" but above I said that this means that the array is immutable but the contents are not.

What is the syntax for an immutable array of mutable characters?

-- 
Derek Parnell
Melbourne, Australia
"Justice for David Hicks!"
skype: derek.j.parnell
May 27, 2007
Walter Bright wrote:
> Derek Parnell wrote:
>>  const(char)[]  // A mutable array of immutable characters?
>>  const(char[])  // An immutable array of mutable characters?
>>  const(const(char)[]) // An immutable array of immutable characters?
>>  char[]         // A mutable array of mutable characters?
>>
>> What will happen with the .reverse and .sort array properties when used
>> with const, invariant, and final qualifiers?
> 
> They'll all fail.

I think it's better to return reversed/sorted copy. This will make such change more backward compatibile.