Thread overview
An Invariant WTH?
Nov 05, 2007
Chad J
Nov 05, 2007
Daniel Keep
Nov 05, 2007
Chad J
Nov 05, 2007
Daniel Keep
Nov 06, 2007
Chad J
Nov 05, 2007
Kris
Nov 06, 2007
Chad J
November 05, 2007
import std.stdio;

void main()
{
  char[] hello = "Hello world!";
  writefln( hello );
}

----------------------

main.d(5): Error: cannot implicitly convert expression ("Hello world!") of type invariant char[12u] to char[]

----------------------

I know that `string hello = "Hello World!";` would cause the desired results, but this makes me have to learn all about constness and invariance just to make very trivial programs.  More learning curve = BAD.  Also, if I wanted to do an inplace toLower or somesuch on the "Hello World!" string, then things get more complicated than in 1.0.

It also disturbs me that "string" is just one of "wstring" and "dstring", and not a more useful generic string type like the dstring that Chris Miller wrote.

Not to mention the massive drain on D community's and Walter's resources that this has caused.

D2.0 just got closures, and I still get the feeling that I don't like const.  So I'm wondering if it is irrational to have this feeling that I'm getting some sort of ugly const thing shoved down my throat.

Bitching and moaning aside, there's got to be a reason we are doing this const thing.  Something good.  Something besides "C/C++ needed it to be less buggy" - C and C++ tend to need a lot of bug fighting measures in places that D conveniently doesn't really need much help in.  Also, something besides "it'll make your program 1% faster".  I was not convinced by those.

It's all cost-benefit.  I'm seeing a lot of cost with little or dubious benefit.  So why should I be convinced that this is the right thing to do?  Why should I be willing to write D2.0 code?
November 05, 2007
"Chad J" <gamerChad@_spamIsBad_gmail.com> wrote in message news:fglnam$eh8$1@digitalmars.com...
> import std.stdio;
>
> void main()
> {
>   char[] hello = "Hello world!";
>   writefln( hello );
> }
>
> ----------------------
>
> main.d(5): Error: cannot implicitly convert expression ("Hello world!") of type invariant char[12u] to char[]
>
> ----------------------
>
> I know that `string hello = "Hello World!";` would cause the desired results, but this makes me have to learn all about constness and invariance just to make very trivial programs.  More learning curve = BAD. Also, if I wanted to do an inplace toLower or somesuch on the "Hello World!" string, then things get more complicated than in 1.0.
>
> It also disturbs me that "string" is just one of "wstring" and "dstring", and not a more useful generic string type like the dstring that Chris Miller wrote.
>
> Not to mention the massive drain on D community's and Walter's resources that this has caused.
>
> D2.0 just got closures, and I still get the feeling that I don't like const.  So I'm wondering if it is irrational to have this feeling that I'm getting some sort of ugly const thing shoved down my throat.
>
> Bitching and moaning aside, there's got to be a reason we are doing this const thing.  Something good.  Something besides "C/C++ needed it to be less buggy" - C and C++ tend to need a lot of bug fighting measures in places that D conveniently doesn't really need much help in.  Also, something besides "it'll make your program 1% faster".  I was not convinced by those.
>
> It's all cost-benefit.  I'm seeing a lot of cost with little or dubious benefit.  So why should I be convinced that this is the right thing to do? Why should I be willing to write D2.0 code?

You're not alone in feeling this way.


November 05, 2007

Chad J wrote:
> import std.stdio;
> 
> void main()
> {
>   char[] hello = "Hello world!";
>   writefln( hello );
> }
> 
> ----------------------
> 
> main.d(5): Error: cannot implicitly convert expression ("Hello world!")
> of type invariant char[12u] to char[]
> 
> ----------------------
> 
> I know that `string hello = "Hello World!";` would cause the desired results, but this makes me have to learn all about constness and invariance just to make very trivial programs.  More learning curve = BAD.  Also, if I wanted to do an inplace toLower or somesuch on the "Hello World!" string, then things get more complicated than in 1.0.

Trying to do an in-place toLower on "Hello World!" is a *BUG*.  The contents of string literals are stored in the data segment, which is supposed to be read-only (apparently not on Windows, though.)  If you took that code and tried to run it on, AFAIK, any non-Windows OS, you'd get segmentation faults.  Then you'd complain that D didn't catch the error; and if not you, then someone else would, because that's what people have done before!  This is one of the major reasons why people want a const system.

> It also disturbs me that "string" is just one of "wstring" and "dstring", and not a more useful generic string type like the dstring that Chris Miller wrote.

I'm not entirely convinced that would be better (although I'm not entirely convinced that it wouldn't.)  Once we have implicit conversions, however, you can probably get away with just using a string struct/class in your own code, and automatically convert to the required array type.

Personally, I've never had an issue with using straight arrays.

> Not to mention the massive drain on D community's and Walter's resources that this has caused.

This is true.  const is a huge, nasty problem.  But keep in mind that before this all started, there were fairly regular posts to the newsgroup asking when D was going to get a const system.  A number of people came in here and said they wouldn't even consider using D until it had a const system to back them up.

It's not like Walter just got up one day and decided "I think I'll design a new const system!"

Well, OK.  Maybe he did.  But it's not like we weren't bugging him to do so :P

> D2.0 just got closures, and I still get the feeling that I don't like const.

<JohnCleese> I'm sorry, but... this is irrelevent.
<MichaelPalin> Leaping from tree to tree down the mighty rivers of
British Columbia...

> So I'm wondering if it is irrational to have this feeling that I'm getting some sort of ugly const thing shoved down my throat.

I'll be clear: I want const.  I seem to be one of the few people who actually grokked and liked the originally proposed const system.  That said, if you don't like something, it's normal to, well... not like it.

> Bitching and moaning aside, there's got to be a reason we are doing this const thing.  Something good.  Something besides "C/C++ needed it to be less buggy" - C and C++ tend to need a lot of bug fighting measures in places that D conveniently doesn't really need much help in.  Also, something besides "it'll make your program 1% faster".  I was not convinced by those.

Again, maybe it's just me, but when I write code, I'm constantly thinking to myself "I really wish I had const here."  One of the big things it buys you is the ability to express intent.  For example, I'm (on and off) writing a full DOM implementation for D.  One of the issues is: what to do with string data.

My two options are: dup every string that comes in, or just reference it.  The problem with the first is that it's much less efficient if I don't need to do those dups.  The problem with the second is that it makes keeping my memory profile down much harder: I can never actually tell whether I "own" a piece of memory or not.

If I had const, I could make two versions of the setter functions, and
only dup if it's actually necessary.  This would be a big gain for me
not because of the efficiency gain, but because I no longer have to go
around worrying about whether a particular method is pass-by-value or
pass-by-reference.  I no longer have to go and look up "now, am I
allowed to change this array, or will that cause Bad Things to happen?"
 I can actually get the compiler to check for me.

> It's all cost-benefit.  I'm seeing a lot of cost with little or dubious benefit.  So why should I be convinced that this is the right thing to do?  Why should I be willing to write D2.0 code?

If you're happy with D 1.0, then stick with that (no, this isn't a "if u dont leik it, get lost!" comment.)  If you want to use the other features of D 2.0, start writing in it and point out where the const system fails.  The example you gave at the start of this post is, in fact, a prime case for *having* a const system, since you didn't even realise you were making a mistake!

Me?  I'm going to wait until Walter unveils the changes to the const system.  Arguing about something that's already been declared obsolete is somewhat pointless :P

	-- Daniel
November 05, 2007
Daniel Keep wrote:
> 
> Chad J wrote:
>> import std.stdio;
>>
>> void main()
>> {
>>   char[] hello = "Hello world!";
>>   writefln( hello );
>> }
>>
>> ----------------------
>>
>> main.d(5): Error: cannot implicitly convert expression ("Hello world!")
>> of type invariant char[12u] to char[]
>>
>> ----------------------
>>
>> I know that `string hello = "Hello World!";` would cause the desired
>> results, but this makes me have to learn all about constness and
>> invariance just to make very trivial programs.  More learning curve =
>> BAD.  Also, if I wanted to do an inplace toLower or somesuch on the
>> "Hello World!" string, then things get more complicated than in 1.0.
> 
> Trying to do an in-place toLower on "Hello World!" is a *BUG*.  The
> contents of string literals are stored in the data segment, which is
> supposed to be read-only (apparently not on Windows, though.)  If you
> took that code and tried to run it on, AFAIK, any non-Windows OS, you'd
> get segmentation faults.  Then you'd complain that D didn't catch the
> error; and if not you, then someone else would, because that's what
> people have done before!  This is one of the major reasons why people
> want a const system.
> 

Hmmm.  I thought the assignment would cause copying, thus it didn't seem necessary to have const in this case.

>> It also disturbs me that "string" is just one of "wstring" and
>> "dstring", and not a more useful generic string type like the dstring
>> that Chris Miller wrote.
> 
> I'm not entirely convinced that would be better (although I'm not
> entirely convinced that it wouldn't.)  Once we have implicit
> conversions, however, you can probably get away with just using a string
> struct/class in your own code, and automatically convert to the required
> array type.
> 
> Personally, I've never had an issue with using straight arrays.
> 

<ramble thats somewhat OT>
I frequently find myself in this situation where I want to iterate over a string, and at the same time be able to index the string an arbitrary number of elements ahead or behind the current one.  Either that, or I want to iterate through 2 strings in parallel, using the same index to do operations on both.  I forget why these things happen, but they do, and foreach is just not adequate for decoding the UTF stuff.  By the very act of iteration, it does define a way to index UTF8 strings, and I wish that definition could be applied to random access.  My other alternative is to use dchars, which just doesn't work that well with phobos, considering everything in phobos uses char[].  I haven't tried writing a dchar[] using program with tango yet.

I wish I could be more thorough about this though.  I believe it deserves more thought on my part.  It's also starting to be less relevant to the whole const discussion, so I'd rather just leave this at "string the keyword can probably be better allocated".
</ramble thats somewhat OT>

>> Not to mention the massive drain on D community's and Walter's resources
>> that this has caused.
> 
> This is true.  const is a huge, nasty problem.  But keep in mind that
> before this all started, there were fairly regular posts to the
> newsgroup asking when D was going to get a const system.  A number of
> people came in here and said they wouldn't even consider using D until
> it had a const system to back them up.
> 
> It's not like Walter just got up one day and decided "I think I'll
> design a new const system!"
> 
> Well, OK.  Maybe he did.  But it's not like we weren't bugging him to do
> so :P
> 

I remember this.  Const was going to be great.  It doesn't seem to be delivering.

Do we have any examples of programs experiencing dramatic bug reduction after switching to D2.0?  Are there benchmarks proving the performance increase?

Well, if the current const system really is considered obsolete, then this stuff can probably wait.

My point is that const seemed to be somewhat of an experimental feature in D.  If the experiment fails, we need to remove it!

>> D2.0 just got closures, and I still get the feeling that I don't like
>> const.
> 
> <JohnCleese> I'm sorry, but... this is irrelevent.
> <MichaelPalin> Leaping from tree to tree down the mighty rivers of
> British Columbia...
> 

The problem is that D1.0 gets the shaft for new features that it would have otherwise benefited from.

>> So I'm wondering if it is irrational to have this feeling that
>> I'm getting some sort of ugly const thing shoved down my throat.
> 
> I'll be clear: I want const.  I seem to be one of the few people who
> actually grokked and liked the originally proposed const system.  That
> said, if you don't like something, it's normal to, well... not like it.
> 
>> Bitching and moaning aside, there's got to be a reason we are doing this
>> const thing.  Something good.  Something besides "C/C++ needed it to be
>> less buggy" - C and C++ tend to need a lot of bug fighting measures in
>> places that D conveniently doesn't really need much help in.  Also,
>> something besides "it'll make your program 1% faster".  I was not
>> convinced by those.
> 
> Again, maybe it's just me, but when I write code, I'm constantly
> thinking to myself "I really wish I had const here."  One of the big
> things it buys you is the ability to express intent.  For example, I'm
> (on and off) writing a full DOM implementation for D.  One of the issues
> is: what to do with string data.
> 
> My two options are: dup every string that comes in, or just reference
> it.  The problem with the first is that it's much less efficient if I
> don't need to do those dups.  The problem with the second is that it
> makes keeping my memory profile down much harder: I can never actually
> tell whether I "own" a piece of memory or not.
> 
> If I had const, I could make two versions of the setter functions, and
> only dup if it's actually necessary.  This would be a big gain for me
> not because of the efficiency gain, but because I no longer have to go
> around worrying about whether a particular method is pass-by-value or
> pass-by-reference.  I no longer have to go and look up "now, am I
> allowed to change this array, or will that cause Bad Things to happen?"
>  I can actually get the compiler to check for me.
> 

The pass-by-ref vs. pass-by-val seems juicy, but I don't think I understand entirely.  How does constness solve this?  Aren't strings ALWAYS referenced to, or are you referring to the reference itself being a value or something referred to?  A simple code snippet demonstrating this would be great (you can refer me to this if it's been done).

>> It's all cost-benefit.  I'm seeing a lot of cost with little or dubious
>> benefit.  So why should I be convinced that this is the right thing to
>> do?  Why should I be willing to write D2.0 code?
> 
> If you're happy with D 1.0, then stick with that (no, this isn't a "if u
> dont leik it, get lost!" comment.)  If you want to use the other
> features of D 2.0, start writing in it and point out where the const
> system fails.  The example you gave at the start of this post is, in
> fact, a prime case for *having* a const system, since you didn't even
> realise you were making a mistake!
> 

Maybe I am stubborn, but that doesn't tell me that D needs a const system.  It tells me that the way string literals are handled is broken and platform dependent.

> Me?  I'm going to wait until Walter unveils the changes to the const
> system.  Arguing about something that's already been declared obsolete
> is somewhat pointless :P
> 
> 	-- Daniel

While I am certainly venting a bit about this, I do want to resolve this somehow.  By "this" I don't mean constness, I mean my personal issues with constness.  Since const doesn't seem to be going away but rather just changing a bit, I am left with one other option: to make me, an angry const-hater, into someone who is not an angry const-hater.
November 05, 2007

Chad J wrote:
> <ramble thats somewhat OT>
> I frequently find myself in this situation where I want to iterate over
> a string, and at the same time be able to index the string an arbitrary
> number of elements ahead or behind the current one.  Either that, or I
> want to iterate through 2 strings in parallel, using the same index to
> do operations on both.  I forget why these things happen, but they do,
> and foreach is just not adequate for decoding the UTF stuff.  By the
> very act of iteration, it does define a way to index UTF8 strings, and I
> wish that definition could be applied to random access.  My other
> alternative is to use dchars, which just doesn't work that well with
> phobos, considering everything in phobos uses char[].  I haven't tried
> writing a dchar[] using program with tango yet.
> 
> I wish I could be more thorough about this though.  I believe it
> deserves more thought on my part.  It's also starting to be less
> relevant to the whole const discussion, so I'd rather just leave this at
> "string the keyword can probably be better allocated".
> </ramble thats somewhat OT>

To me, that suggests that the standard library is simply incomplete :P

The problem with random access in a UTF-8 or UTF-16 string is that, AFAIK, there's no way to do it efficiently.  You have to decode the *entire* string up to that index to find it.  The way the dstring structure works is by switching to UTF-16 or UTF-32 as soon as you get multiunit codepoints showing up.

I suppose in the end it really depends on what you're doing with your strings, and how frequently you do it.

> My point is that const seemed to be somewhat of an experimental feature in D.  If the experiment fails, we need to remove it!

Agreed.  The trick will be finding an agreement for the conditions of failure :P

>>> D2.0 just got closures, and I still get the feeling that I don't like const.
>>
>> <JohnCleese> I'm sorry, but... this is irrelevent.
>> <MichaelPalin> Leaping from tree to tree down the mighty rivers of
>> British Columbia...
>>
> 
> The problem is that D1.0 gets the shaft for new features that it would have otherwise benefited from.

True.  That said, since I have a fairly big, complex project written in
D 1.0, I'm really very happy with how the whole feature-freeze has
turned out.  It means I don't have to go fixing things that broke when I
updated the compiler to squash a bug (which actually happened a few times.)

> The pass-by-ref vs. pass-by-val seems juicy, but I don't think I understand entirely.  How does constness solve this?  Aren't strings ALWAYS referenced to, or are you referring to the reference itself being a value or something referred to?  A simple code snippet demonstrating this would be great (you can refer me to this if it's been done).

The funny thing is that an invariant array *works* like it's pass-by-value, basically by virtue of the fact that no one else can change it.

As an example, you can't do this:

int a = 1;
int b = a;
b += 5;
assert( a == 6 ); // Nope

But you *can* do this:

char[] a = "foo";
char[] b = a;
b[] = "bar";
assert( a == "bar" ); // Yup

While invariant strings act like 'int' does:

string a = "foo";
string b = a;
//b[] = "bar"; // Doesn't work
b = "bar";
assert( a == "bar" ); // Nope

A practical use of this: in DOM, you can do this:

char[] name = "tag-name";
new Element(name);

The problem is that I don't know who "owns" the string that gets passed in.  Currently, for the sake of efficiency, I don't dup strings passed in.  However, this means that if anyone even accidentally changes the value pointed to by 'name', it can screw up the DOM tree.

If I use 'string', on the other hand, I can pass them around willy-nilly as values.  It's the same as passing around an int and not having to worry about the value of the int changing (unless you're using Java in which case the value of an int *can* apparently change.)  You can't redefine, say, 0 to mean 8.  Yes, they're still really references, but they work like values.

So the ctor would probably become:

this(char[] tagName)
{
    this.tagName = tagName.idup; // Need an immutable copy
}

this(string tagName)
{
    this.tagName = tagName; // No copy needed
}

Incidentally, this also protects me from having people (ie: myself when I'm not paying attention) go element.tagName[0] = 'x' or other silly crap like that.

>>> It's all cost-benefit.  I'm seeing a lot of cost with little or dubious benefit.  So why should I be convinced that this is the right thing to do?  Why should I be willing to write D2.0 code?
>>
>> If you're happy with D 1.0, then stick with that (no, this isn't a "if u dont leik it, get lost!" comment.)  If you want to use the other features of D 2.0, start writing in it and point out where the const system fails.  The example you gave at the start of this post is, in fact, a prime case for *having* a const system, since you didn't even realise you were making a mistake!
>>
> 
> Maybe I am stubborn, but that doesn't tell me that D needs a const system.  It tells me that the way string literals are handled is broken and platform dependent.

It's more like a bug in Windows :P  For instance, this cropped up in #d.tango a while ago:

    char[] tmp = "000";
    Integer.format(tmp, cast(long) mode, Integer.Style.Octal);

What no one realised was that this piece of code actually *redefines* the meaning of "000" every time it's run.  Here's a more obvious example:

    char[] tmp1 = "000";
    char[] tmp2 = "000";
    tmp1[1] = '!';

    writefln("tmp1: %s, tmp2: %s", tmp1, tmp2);

This outputs "tmp1: 0!0, tmp2: 0!0".  If you're unlucky, this will manifest itself in your code as *really weird* errors that are impossible to track down.

>> Me?  I'm going to wait until Walter unveils the changes to the const system.  Arguing about something that's already been declared obsolete is somewhat pointless :P
>>
>>     -- Daniel
> 
> While I am certainly venting a bit about this, I do want to resolve this somehow.  By "this" I don't mean constness, I mean my personal issues with constness.  Since const doesn't seem to be going away but rather just changing a bit, I am left with one other option: to make me, an angry const-hater, into someone who is not an angry const-hater.

I don't know if there's much I can say to convince you.  I think this is something that, until you *need* it, just seems like a pain-in-the-arse imposition.  *I* used to think that languages with const were just trying to get in my way, until I started running into situations where it actually made my code simpler.

	-- Daniel
November 05, 2007
Chad: sounds like you need Tango for your text processing needs ...


"Chad J" <gamerChad@_spamIsBad_gmail.com> wrote in message news:fgm0v1$qug$1@digitalmars.com...
> Daniel Keep wrote:
>>
>> Chad J wrote:
>>> import std.stdio;
>>>
>>> void main()
>>> {
>>>   char[] hello = "Hello world!";
>>>   writefln( hello );
>>> }
>>>
>>> ----------------------
>>>
>>> main.d(5): Error: cannot implicitly convert expression ("Hello world!")
>>> of type invariant char[12u] to char[]
>>>
>>> ----------------------
>>>
>>> I know that `string hello = "Hello World!";` would cause the desired results, but this makes me have to learn all about constness and invariance just to make very trivial programs.  More learning curve = BAD.  Also, if I wanted to do an inplace toLower or somesuch on the "Hello World!" string, then things get more complicated than in 1.0.
>>
>> Trying to do an in-place toLower on "Hello World!" is a *BUG*.  The contents of string literals are stored in the data segment, which is supposed to be read-only (apparently not on Windows, though.)  If you took that code and tried to run it on, AFAIK, any non-Windows OS, you'd get segmentation faults.  Then you'd complain that D didn't catch the error; and if not you, then someone else would, because that's what people have done before!  This is one of the major reasons why people want a const system.
>>
>
> Hmmm.  I thought the assignment would cause copying, thus it didn't seem necessary to have const in this case.
>
>>> It also disturbs me that "string" is just one of "wstring" and "dstring", and not a more useful generic string type like the dstring that Chris Miller wrote.
>>
>> I'm not entirely convinced that would be better (although I'm not entirely convinced that it wouldn't.)  Once we have implicit conversions, however, you can probably get away with just using a string struct/class in your own code, and automatically convert to the required array type.
>>
>> Personally, I've never had an issue with using straight arrays.
>>
>
> <ramble thats somewhat OT>
> I frequently find myself in this situation where I want to iterate over a
> string, and at the same time be able to index the string an arbitrary
> number of elements ahead or behind the current one.  Either that, or I
> want to iterate through 2 strings in parallel, using the same index to do
> operations on both.  I forget why these things happen, but they do, and
> foreach is just not adequate for decoding the UTF stuff.  By the very act
> of iteration, it does define a way to index UTF8 strings, and I wish that
> definition could be applied to random access.  My other alternative is to
> use dchars, which just doesn't work that well with phobos, considering
> everything in phobos uses char[].  I haven't tried writing a dchar[] using
> program with tango yet.
>
> I wish I could be more thorough about this though.  I believe it deserves
> more thought on my part.  It's also starting to be less relevant to the
> whole const discussion, so I'd rather just leave this at "string the
> keyword can probably be better allocated".
> </ramble thats somewhat OT>
>
>>> Not to mention the massive drain on D community's and Walter's resources that this has caused.
>>
>> This is true.  const is a huge, nasty problem.  But keep in mind that before this all started, there were fairly regular posts to the newsgroup asking when D was going to get a const system.  A number of people came in here and said they wouldn't even consider using D until it had a const system to back them up.
>>
>> It's not like Walter just got up one day and decided "I think I'll design a new const system!"
>>
>> Well, OK.  Maybe he did.  But it's not like we weren't bugging him to do so :P
>>
>
> I remember this.  Const was going to be great.  It doesn't seem to be delivering.
>
> Do we have any examples of programs experiencing dramatic bug reduction after switching to D2.0?  Are there benchmarks proving the performance increase?
>
> Well, if the current const system really is considered obsolete, then this stuff can probably wait.
>
> My point is that const seemed to be somewhat of an experimental feature in D.  If the experiment fails, we need to remove it!
>
>>> D2.0 just got closures, and I still get the feeling that I don't like const.
>>
>> <JohnCleese> I'm sorry, but... this is irrelevent.
>> <MichaelPalin> Leaping from tree to tree down the mighty rivers of
>> British Columbia...
>>
>
> The problem is that D1.0 gets the shaft for new features that it would have otherwise benefited from.
>
>>> So I'm wondering if it is irrational to have this feeling that I'm getting some sort of ugly const thing shoved down my throat.
>>
>> I'll be clear: I want const.  I seem to be one of the few people who actually grokked and liked the originally proposed const system.  That said, if you don't like something, it's normal to, well... not like it.
>>
>>> Bitching and moaning aside, there's got to be a reason we are doing this const thing.  Something good.  Something besides "C/C++ needed it to be less buggy" - C and C++ tend to need a lot of bug fighting measures in places that D conveniently doesn't really need much help in.  Also, something besides "it'll make your program 1% faster".  I was not convinced by those.
>>
>> Again, maybe it's just me, but when I write code, I'm constantly thinking to myself "I really wish I had const here."  One of the big things it buys you is the ability to express intent.  For example, I'm (on and off) writing a full DOM implementation for D.  One of the issues is: what to do with string data.
>>
>> My two options are: dup every string that comes in, or just reference it.  The problem with the first is that it's much less efficient if I don't need to do those dups.  The problem with the second is that it makes keeping my memory profile down much harder: I can never actually tell whether I "own" a piece of memory or not.
>>
>> If I had const, I could make two versions of the setter functions, and
>> only dup if it's actually necessary.  This would be a big gain for me
>> not because of the efficiency gain, but because I no longer have to go
>> around worrying about whether a particular method is pass-by-value or
>> pass-by-reference.  I no longer have to go and look up "now, am I
>> allowed to change this array, or will that cause Bad Things to happen?"
>>  I can actually get the compiler to check for me.
>>
>
> The pass-by-ref vs. pass-by-val seems juicy, but I don't think I understand entirely.  How does constness solve this?  Aren't strings ALWAYS referenced to, or are you referring to the reference itself being a value or something referred to?  A simple code snippet demonstrating this would be great (you can refer me to this if it's been done).
>
>>> It's all cost-benefit.  I'm seeing a lot of cost with little or dubious benefit.  So why should I be convinced that this is the right thing to do?  Why should I be willing to write D2.0 code?
>>
>> If you're happy with D 1.0, then stick with that (no, this isn't a "if u dont leik it, get lost!" comment.)  If you want to use the other features of D 2.0, start writing in it and point out where the const system fails.  The example you gave at the start of this post is, in fact, a prime case for *having* a const system, since you didn't even realise you were making a mistake!
>>
>
> Maybe I am stubborn, but that doesn't tell me that D needs a const system. It tells me that the way string literals are handled is broken and platform dependent.
>
>> Me?  I'm going to wait until Walter unveils the changes to the const system.  Arguing about something that's already been declared obsolete is somewhat pointless :P
>>
>> -- Daniel
>
> While I am certainly venting a bit about this, I do want to resolve this somehow.  By "this" I don't mean constness, I mean my personal issues with constness.  Since const doesn't seem to be going away but rather just changing a bit, I am left with one other option: to make me, an angry const-hater, into someone who is not an angry const-hater.


November 06, 2007
Daniel Keep wrote:
> 
>> The pass-by-ref vs. pass-by-val seems juicy, but I don't think I
>> understand entirely.  How does constness solve this?  Aren't strings
>> ALWAYS referenced to, or are you referring to the reference itself being
>> a value or something referred to?  A simple code snippet demonstrating
>> this would be great (you can refer me to this if it's been done).
> 
> The funny thing is that an invariant array *works* like it's
> pass-by-value, basically by virtue of the fact that no one else can
> change it.
> 
> As an example, you can't do this:
> 
> int a = 1;
> int b = a;
> b += 5;
> assert( a == 6 ); // Nope
> 
> But you *can* do this:
> 
> char[] a = "foo";
> char[] b = a;
> b[] = "bar";
> assert( a == "bar" ); // Yup
> 
> While invariant strings act like 'int' does:
> 
> string a = "foo";
> string b = a;
> //b[] = "bar"; // Doesn't work
> b = "bar";
> assert( a == "bar" ); // Nope
> 
> A practical use of this: in DOM, you can do this:
> 
> char[] name = "tag-name";
> new Element(name);
> 
> The problem is that I don't know who "owns" the string that gets passed
> in.  Currently, for the sake of efficiency, I don't dup strings passed
> in.  However, this means that if anyone even accidentally changes the
> value pointed to by 'name', it can screw up the DOM tree.
> 
> If I use 'string', on the other hand, I can pass them around willy-nilly
> as values.  It's the same as passing around an int and not having to
> worry about the value of the int changing (unless you're using Java in
> which case the value of an int *can* apparently change.)  You can't
> redefine, say, 0 to mean 8.  Yes, they're still really references, but
> they work like values.
> 
> So the ctor would probably become:
> 
> this(char[] tagName)
> {
>     this.tagName = tagName.idup; // Need an immutable copy
> }
> 
> this(string tagName)
> {
>     this.tagName = tagName; // No copy needed
> }
> 
> Incidentally, this also protects me from having people (ie: myself when
> I'm not paying attention) go element.tagName[0] = 'x' or other silly
> crap like that.
> 

I like where that's going.  Thanks for that.

I'm still not convinced that it's worth the increased complexity in the
language, but that doesn't affect me as a programmer so much, which
means I can deal with it.  Now I at least have a design pattern or two
that leverages this constness thing.

>>>> It's all cost-benefit.  I'm seeing a lot of cost with little or dubious
>>>> benefit.  So why should I be convinced that this is the right thing to
>>>> do?  Why should I be willing to write D2.0 code?
>>> If you're happy with D 1.0, then stick with that (no, this isn't a "if u
>>> dont leik it, get lost!" comment.)  If you want to use the other
>>> features of D 2.0, start writing in it and point out where the const
>>> system fails.  The example you gave at the start of this post is, in
>>> fact, a prime case for *having* a const system, since you didn't even
>>> realise you were making a mistake!
>>>
>> Maybe I am stubborn, but that doesn't tell me that D needs a const
>> system.  It tells me that the way string literals are handled is broken
>> and platform dependent.
> 
> It's more like a bug in Windows :P  For instance, this cropped up in
> #d.tango a while ago:
> 
>     char[] tmp = "000";
>     Integer.format(tmp, cast(long) mode, Integer.Style.Octal);
> 
> What no one realised was that this piece of code actually *redefines*
> the meaning of "000" every time it's run.  Here's a more obvious example:
> 
>     char[] tmp1 = "000";
>     char[] tmp2 = "000";
>     tmp1[1] = '!';
> 
>     writefln("tmp1: %s, tmp2: %s", tmp1, tmp2);
> 
> This outputs "tmp1: 0!0, tmp2: 0!0".  If you're unlucky, this will
> manifest itself in your code as *really weird* errors that are
> impossible to track down.
> 

Yuck.  This is all wrong.  Windows is wrong, and D is too.

I thought that part of the design philosophy in D is that program
correctness comes first, while at the same time giving the programmer
the tools needed to optimize as far as possible.  The way literals are
handled in D1.0 violates that.

In this case the programmer assigns to a variable from a literal.  The following things may happen:

              +----------------------------------+
              | action taken by the language     |
              |----------------------------------|
              | dup on assign | ref the literal  |
--------------+---------------+------------------+
string only   |   efficiency  |  everything is   |
read          |     loss*     |      fine        |
--------------+---------------+------------------+
string gets   | everything is | segfault or hard |
modified      |     fine      | to find bugs     |
--------------+---------------+------------------+

* This may very well be a heap allocation if the compiler doesn't know what the programmer does with the duplicate.  Escape analysis could potentially reduce some cases to a stack allocation with a mem copy. "Scope" allocated variables and manual stack allocation would also provide means for the programmer to optimize away the inefficiency.  Use of static variables can also turn it into a one time startup cost.

I think that the "dup on assign" path would be superior.  I get this feeling that the loss in performance would have been moot compared to the obscure bugs caused.  This is especially the case if the programmers who care about speed apply the trivial optimizations like static and scope variables.

Constness does seem to provide a better answer to this, though it'd be nice if there was an implicit dup for literals being assigned to non-invariant/non-const types, or at least a better error message.

>>> Me?  I'm going to wait until Walter unveils the changes to the const
>>> system.  Arguing about something that's already been declared obsolete
>>> is somewhat pointless :P
>>>
>>>     -- Daniel
>> While I am certainly venting a bit about this, I do want to resolve this
>> somehow.  By "this" I don't mean constness, I mean my personal issues
>> with constness.  Since const doesn't seem to be going away but rather
>> just changing a bit, I am left with one other option: to make me, an
>> angry const-hater, into someone who is not an angry const-hater.
> 
> I don't know if there's much I can say to convince you.  I think this is
> something that, until you *need* it, just seems like a pain-in-the-arse
> imposition.  *I* used to think that languages with const were just
> trying to get in my way, until I started running into situations where
> it actually made my code simpler.
> 
> 	-- Daniel

Well, thanks for trying at least.
November 06, 2007
Kris wrote:
> Chad: sounds like you need Tango for your text processing needs ...
> 

Yeah I've been itching to try Tango on a project where I run into these things.  I get the feeling it uses templates to sidestep the whole char[]/wchar[]/dchar[] crap.  Then I'd be able to just use dchar[] all the time and thus get my random indexing.  Computers like working with 32 bit wide things anyways.  So yeah, I've been convinced of this for a year, but that's also been the year when I haven't done much coding.