Community

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.

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/

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.

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.

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.

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.

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.

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

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