May 26, 2007
Under the new const/invariant/final regime, what are strings going to be ? Experience with other languages suggest that strings should be immutable. To express an array of const chars, one would write:

	const(char)[]

but while that's clear, it doesn't just flow off the keyboard. Strings are so common this needs an alias, so:

	alias const(char)[] cstring;

Why cstring? Because 'string' appears as both a module name and a common variable name. cstring also implies wstring for wchar strings, and dstring for dchars.

String literals, on the other hand, will be invariant (which means they can be stuffed into read-only memory). So,
	typeof("abc")
will be:
	invariant(char)[3]

Invariants can be implicitly cast to const.

In my playing around with source code, using cstring's seems to work out rather nicely.

So, why not alias cstring to invariant(char)[] ? That way strings really would be immutable. The reason is that mutables cannot be implicitly cast to invariant, meaning that there'd be a lot of casts in the code. Casts are a sledgehammer, and a coding style that requires too many casts is a bad coding style.
May 26, 2007

Walter Bright wrote:
> Under the new const/invariant/final regime, what are strings going to be ? Experience with other languages suggest that strings should be immutable. To express an array of const chars, one would write:
> 
>     const(char)[]
> 
> but while that's clear, it doesn't just flow off the keyboard. Strings are so common this needs an alias, so:
> 
>     alias const(char)[] cstring;
> 
> Why cstring? Because 'string' appears as both a module name and a common variable name. cstring also implies wstring for wchar strings, and dstring for dchars.
> 
> String literals, on the other hand, will be invariant (which means they
> can be stuffed into read-only memory). So,
>     typeof("abc")
> will be:
>     invariant(char)[3]
> 
> Invariants can be implicitly cast to const.
> 
> In my playing around with source code, using cstring's seems to work out rather nicely.
> 
> So, why not alias cstring to invariant(char)[] ? That way strings really would be immutable. The reason is that mutables cannot be implicitly cast to invariant, meaning that there'd be a lot of casts in the code. Casts are a sledgehammer, and a coding style that requires too many casts is a bad coding style.

Thanks for the update; I'm happy to have const strings, and use char[] manually when I want to mutate something.

One question though: are the parens necessary?  I was under the impression that const and invariant applied to reference types, so it would be const char[] or const(char[]), since char by itself is just a value type.

...this is going to turn into one of those mega threads where we all run around in circles trying to work out which one is which, isn't it?

	-- Daniel

-- 
int getRandomNumber()
{
    return 4; // chosen by fair dice roll.
              // guaranteed to be random.
}

http://xkcd.com/

v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP  http://hackerkey.com/
May 26, 2007
Daniel Keep wrote:
> One question though: are the parens necessary?  I was under the
> impression that const and invariant applied to reference types, so it
> would be const char[] or const(char[]), since char by itself is just a
> value type.

const(char)[] => array of const characters
const char[] => const array of const characters
const(char[]) => const array of const characters

Think of const as if it were a template:

	Const!(T)

which returns a const version of its argument.

const without any parens means it applies to the whole type.
May 26, 2007
Walter Bright wrote:
> Daniel Keep wrote:
> 
> const(char)[] => array of const characters
> const char[] => const array of const characters
> const(char[]) => const array of const characters
> 
> Think of const as if it were a template:
> 
>     Const!(T)
> 
> which returns a const version of its argument.
> 
> const without any parens means it applies to the whole type.

Looking mighty fine.
May 26, 2007
Myron Alexander wrote:
> Walter Bright wrote:
>> Daniel Keep wrote:
>>
>> const(char)[] => array of const characters
>> const char[] => const array of const characters
>> const(char[]) => const array of const characters
>>
>> Think of const as if it were a template:
>>
>>     Const!(T)
>>
>> which returns a const version of its argument.
>>
>> const without any parens means it applies to the whole type.
> 
> Looking mighty fine.

I like it a lot better than the C++ "here a const, there a const, everywhere a const const" like:

	const char * const * const p;

etc. instead of:

	const(char**) p;

Const in D is transitive, so const(char**) is equivalent to:

	const(const(const(char)*)*)

And no, it is not possible to have a pointer to const pointer to mutable. It is both not possible syntactically to declare it, nor is it 
 semantically allowed. You can force the issue with casts (which allow you to do whatever you *need* to do), but the result will be undefined behavior.
May 26, 2007
Nice idea.  I am only concerned that people will see "cstring" and think "null-terminated "C" string".  Not that that should be a deciding factor by any means of course.

Walter Bright Wrote:

> Under the new const/invariant/final regime, what are strings going to be ? Experience with other languages suggest that strings should be immutable. To express an array of const chars, one would write:
> 
> 	const(char)[]
> 
> but while that's clear, it doesn't just flow off the keyboard. Strings are so common this needs an alias, so:
> 
> 	alias const(char)[] cstring;
> 
> Why cstring? Because 'string' appears as both a module name and a common variable name. cstring also implies wstring for wchar strings, and dstring for dchars.
> 
> String literals, on the other hand, will be invariant (which means they
> can be stuffed into read-only memory). So,
> 	typeof("abc")
> will be:
> 	invariant(char)[3]
> 
> Invariants can be implicitly cast to const.
> 
> In my playing around with source code, using cstring's seems to work out rather nicely.
> 
> So, why not alias cstring to invariant(char)[] ? That way strings really would be immutable. The reason is that mutables cannot be implicitly cast to invariant, meaning that there'd be a lot of casts in the code. Casts are a sledgehammer, and a coding style that requires too many casts is a bad coding style.

May 26, 2007
Howard Berkey wrote:
> Nice idea.  I am only concerned that people will see "cstring" and think "null-terminated "C" string".  Not that that should be a deciding factor by any means of course.
> 


When I first read Walter's post, I also thought null-terminated strings. 


I even had it as an alias for toString (converting C string to char[]) as a means to get around the name conflict with Object but I shortened it to "str".

I cannot think of another name but "cstring" will cause confusion and defeats the "obvious" rule.
May 26, 2007
Myron Alexander wrote:
> Howard Berkey wrote:
>> Nice idea.  I am only concerned that people will see "cstring" and think "null-terminated "C" string".  Not that that should be a deciding factor by any means of course.
>>
> 
> 
> When I first read Walter's post, I also thought null-terminated strings.
> 
> I even had it as an alias for toString (converting C string to char[]) as a means to get around the name conflict with Object but I shortened it to "str".
> 
> I cannot think of another name but "cstring" will cause confusion and defeats the "obvious" rule.

Here's a possibility:

Instead of cstring, wstring, dstring - charstr, widestr, dblstr.
May 26, 2007
Walter Bright wrote:
> Under the new const/invariant/final regime, what are strings going to be ? Experience with other languages suggest that strings should be immutable. To express an array of const chars, one would write:
> 
>     const(char)[]
> 
> but while that's clear, it doesn't just flow off the keyboard. Strings are so common this needs an alias, so:
> 
>     alias const(char)[] cstring;
> 
> Why cstring? Because 'string' appears as both a module name and a common variable name. cstring also implies wstring for wchar strings, and dstring for dchars.
> 
> String literals, on the other hand, will be invariant (which means they can be stuffed into read-only memory). So,
>     typeof("abc")
> will be:
>     invariant(char)[3]
> 
> Invariants can be implicitly cast to const.
> 
> In my playing around with source code, using cstring's seems to work out rather nicely.
> 
> So, why not alias cstring to invariant(char)[] ? That way strings really would be immutable. The reason is that mutables cannot be implicitly cast to invariant, meaning that there'd be a lot of casts in the code. Casts are a sledgehammer, and a coding style that requires too many casts is a bad coding style.


So basically most functions that take a char[] now would be changed to take a cstring in your thinking?

Is it also correct to say that cstring would be used in the places where one would use const char* or const std::string&  in C++?

If so that sounds ok to me.  But about the naming ... I have to agree that my first thought was "C compatible null terminated string" too, like std::string's  .c_str() method in C++.  I can probably live with that but I don't like the inconsistency with c/w/d.

Plain 'string' really does make the most sense.
plain   'w'     'd'
======= =====   =====
char    wchar   dchar
string  wstring dstring

It wouldn't be quite as bad if you uniformly apply the 'c' to all of them (using 'c' as a flag for constness):
plain   'w'      'd'
======= =====    =====
char    wchar    dchar
cstring wcstring dcstring
or
cstring cwstring cdstring

Some people already alias char[] to string.  As far as I've heard they haven't run into conflicts with the module name, or with people naming variables 'string'.

Question: if you have an alias like
alias char[] string;

'const string' automatically applies const to both the char and the [], right?  Is that something to be worried about?

--bb
May 26, 2007
Walter Bright wrote:
> Under the new const/invariant/final regime, what are strings going to be ? Experience with other languages suggest that strings should be immutable. To express an array of const chars, one would write:
> 
>     const(char)[]
> 
...
> String literals, on the other hand, will be invariant (which means they can be stuffed into read-only memory). So,
>     typeof("abc")
> will be:
>     invariant(char)[3]

The thing I don't get about this syntax is what happens when you take off the [].

1.   invariant(char) c = 'b'; // c is 'b' now, and will never change.
2.   final(char) d = 'b';     // but calling it final means the same...
3.   const(char) e = 'b';     // ummm... what?

It seems like const(char) is a constant char -- one that can't change. Does that make final obsolete?

Also, I can't see any difference between const(char) and invariant(char), since neither can ever be rebound. In that case, if I assume that they are identical types, how can an array of const(char) be different from an array of invariant(char)?

-- Reiner
« First   ‹ Prev
1 2 3 4 5 6 7 8 9
Top | Discussion index | About this forum | D home