March 09, 2009
Steve Schveighoffer wrote:
> On Sun, 08 Mar 2009 17:24:09 -0700, Walter Bright wrote:
> 
>> Derek Parnell wrote:
>>> I know that a better way to code this example would have been to use
>>> the .idup functionality, but that is not the point. I relied on the
>>> compiler ensuring that everything declared as immutable would not be
>>> modified. The compiler failed.
>> It is the same issue. When you use a cast, you are *explicitly*
>> defeating the language's type checking ability. It means that the onus
>> is on the one doing the cast to get it right.
> 
> Except when you want invariant data, then cast is *required*.

Not at all. Calling idup (or, more elegantly, to!TargetType) or assumeUnique under the circumstances documented by assumeUnique are all safe. Sometimes the price for added safety is one extra copy. But the added safety is worth it more often than not.

As far as signatures of functions in std.string, I agree that those not needing a string of immutable characters should just accept in Char[] (where Char is one of the three character types). That should make people using mutable and immutable strings equally joyous.

> At that point, it is a language feature, not a defeat of the typesystem.  I think there is some merit to the arguments presented in this thread, but I don't think the answer is to get rid of invariant.  Perhaps make the compiler more strict when creating invariant data?  I liked the ideas that people presented about having unique mutable references (before and in this thread).  This might even be solvable in a library given all the advances in structs.

Unique has been discussed extensively a couple of years ago when we were defining const and immutable. We decided to forgo it and go with assumeUnique.

> So it's not exactly the same issue, because in one you are doing something totally useless and stupid.  And in the other, it is a language *requirement* to use casting to get invariant data.  However, in both cases, the onus is on the developer, which sucks in the latter case...

NO. It is not a language requirement. If what you have is mutable data and someone else wants immutable data, make a copy.

> Walter: Use invariant when you can, it's the best!
> User: ok, how do I use it?
> Walter: You need to cast mutable data to invariant, but it's on you to make sure nobody changes the original mutable data.  Casting circumvents the typesystem, so the compiler can't help you.
> User: :(

Casts to immutable should not be part of most programs.


Andrei
March 09, 2009
Steve Schveighoffer wrote:
> Walter: Use invariant when you can, it's the best!
> User: ok, how do I use it?
> Walter: You need to cast mutable data to invariant, but it's on you to make sure nobody changes the original mutable data.  Casting circumvents the typesystem, so the compiler can't help you.
> User: :(

Unfortunately, we could not come up with a typesafe scheme for going from mutable to immutable that was reasonable. The transition is up to the user to do correctly, but it isn't a terrible burden, and is simple to get right.
March 09, 2009
Walter Bright wrote:
> Steve Schveighoffer wrote:
>> Walter: Use invariant when you can, it's the best!
>> User: ok, how do I use it?
>> Walter: You need to cast mutable data to invariant, but it's on you to make sure nobody changes the original mutable data.  Casting circumvents the typesystem, so the compiler can't help you.
>> User: :(
> 
> Unfortunately, we could not come up with a typesafe scheme for going from mutable to immutable that was reasonable. The transition is up to the user to do correctly, but it isn't a terrible burden, and is simple to get right.

In fact, since we last discussed that, dmd technology has made enough strides (particularly wrt manipulation of copies) that we can define Unique!T and something a la Java's StringBuilder with ease. Unfortunately current bugs in constructor implementation delay definition of such artifacts.


Andrei
March 09, 2009
Sun, 08 Mar 2009 19:24:32 -0700, Andrei Alexandrescu wrote:

> As far as signatures of functions in std.string, I agree that those not needing a string of immutable characters should just accept in Char[] (where Char is one of the three character types). That should make people using mutable and immutable strings equally joyous.

So you agree that *the standard library* should avoid using immutable when it's not strictly necessary after all.  This is quite in contrary to what Walter says.  Now the question is, how any *other* libraries differ?  I usually don't care about how you use immutable in your personal code.  But if there is an XML library which takes immutables everywhere,  it seriously limits my freedom in chosing my coding style.

Immutable string manipulation produces tons of garbage objects.  Every time you want to replace '\\' with '/' you get garbage, if not as many times as you encounter '\\' in the string.  This is something we avoided at any cost in mobile Java games.  This is the attitude which makes "large" Java applications so memory-hungry.  I have a hard time to believe this magically became OK in D.
March 09, 2009
Sergey Gromov wrote:
> Sun, 08 Mar 2009 19:24:32 -0700, Andrei Alexandrescu wrote:
> 
>> As far as signatures of functions in std.string, I agree that those not needing a string of immutable characters should just accept in Char[] (where Char is one of the three character types). That should make people using mutable and immutable strings equally joyous.
> 
> So you agree that *the standard library* should avoid using immutable
> when it's not strictly necessary after all.

I do.

> This is quite in contrary
> to what Walter says.

It is. This may be because of a slight difference in philosophy; I think any entity (function, type) of the standard library should accept the most general types it could conceivably work with. In fact I'd be happy put all or most significant algorithms in std.string inside std.algorithm.

  Now the question is, how any *other* libraries
> differ?  I usually don't care about how you use immutable in your
> personal code.  But if there is an XML library which takes immutables
> everywhere,  it seriously limits my freedom in chosing my coding style.

I agree but disagree with "seriously".

> Immutable string manipulation produces tons of garbage objects.

This I disagree with. There may be extra copies, but you also save other copies. Also there's never risky aliasing - coding with immutable strings is safe. D simply can't afford to seriously suggest in this day and age a programming style with aliased mutable strings.

> Every
> time you want to replace '\\' with '/' you get garbage, if not as many
> times as you encounter '\\' in the string.  This is something we avoided
> at any cost in mobile Java games.  This is the attitude which makes
> "large" Java applications so memory-hungry.  I have a hard time to
> believe this magically became OK in D.

It does become OK (albeit not magically) in D because D does offer you the option to work with char[] if you need to. I understand that the problem of you calling into libraries only taking string still remains, but really you can't have everything. I think we're in better shape than most languages.


Andrei
March 09, 2009
Andrei Alexandrescu wrote:
> As far as signatures of functions in std.string, I agree that those not needing a string of immutable characters should just accept in Char[] (where Char is one of the three character types). That should make people using mutable and immutable strings equally joyous.

Also std.conv (especially the scheduled-to-be-deprecated toInt(), etc),
and probably also the functions in std.file, such as exists().
March 09, 2009
Don wrote:
> Andrei Alexandrescu wrote:
>> As far as signatures of functions in std.string, I agree that those not needing a string of immutable characters should just accept in Char[] (where Char is one of the three character types). That should make people using mutable and immutable strings equally joyous.
> 
> Also std.conv (especially the scheduled-to-be-deprecated toInt(), etc),
> and probably also the functions in std.file, such as exists().

Yah. That's fixed already, but I concluded I can't check in my changes to phobos until a few bugs are fixed, notably 2674 (http://d.puremagic.com/issues/show_bug.cgi?id=2674). Please vote up :o).


Andrei
March 09, 2009
Andrei Alexandrescu wrote:
> Don wrote:
>> Andrei Alexandrescu wrote:
>>> As far as signatures of functions in std.string, I agree that those not needing a string of immutable characters should just accept in Char[] (where Char is one of the three character types). That should make people using mutable and immutable strings equally joyous.
>>
>> Also std.conv (especially the scheduled-to-be-deprecated toInt(), etc),
>> and probably also the functions in std.file, such as exists().
> 
> Yah. That's fixed already, but I concluded I can't check in my changes to phobos until a few bugs are fixed, notably 2674 (http://d.puremagic.com/issues/show_bug.cgi?id=2674). Please vote up :o).
> 
> 
> Andrei
Yes.
BTW, in my own code, a major reason why string -> const(char)[] is such a necessary change is that std.stream.readLine() returns 'char[]', not 'string'. So you can hardly do anything without a cast or an idup.

Don.
March 09, 2009
On Sun, 08 Mar 2009 20:51:39 -0700, Andrei Alexandrescu wrote:

> Walter Bright wrote:
>> Steve Schveighoffer wrote:
>>> Walter: Use invariant when you can, it's the best! User: ok, how do I
>>> use it?
>>> Walter: You need to cast mutable data to invariant, but it's on you to
>>> make sure nobody changes the original mutable data.  Casting
>>> circumvents the typesystem, so the compiler can't help you. User: :(
>> 
>> Unfortunately, we could not come up with a typesafe scheme for going from mutable to immutable that was reasonable. The transition is up to the user to do correctly, but it isn't a terrible burden, and is simple to get right.
> 
> In fact, since we last discussed that, dmd technology has made enough strides (particularly wrt manipulation of copies) that we can define Unique!T and something a la Java's StringBuilder with ease. Unfortunately current bugs in constructor implementation delay definition of such artifacts.

Yes, please fix!

-Steve
March 09, 2009
Steven Schveighoffer wrote:
> On Sun, 08 Mar 2009 20:51:39 -0700, Andrei Alexandrescu wrote:
> 
>> Walter Bright wrote:
>>> Steve Schveighoffer wrote:
>>>> Walter: Use invariant when you can, it's the best! User: ok, how do I
>>>> use it?
>>>> Walter: You need to cast mutable data to invariant, but it's on you to
>>>> make sure nobody changes the original mutable data.  Casting
>>>> circumvents the typesystem, so the compiler can't help you. User: :(
>>> Unfortunately, we could not come up with a typesafe scheme for going
>>> from mutable to immutable that was reasonable. The transition is up to
>>> the user to do correctly, but it isn't a terrible burden, and is simple
>>> to get right.
>> In fact, since we last discussed that, dmd technology has made enough
>> strides (particularly wrt manipulation of copies) that we can define
>> Unique!T and something a la Java's StringBuilder with ease.
>> Unfortunately current bugs in constructor implementation delay
>> definition of such artifacts.
> 
> Yes, please fix!
> 
> -Steve

Please vote up:

http://d.puremagic.com/issues/show_bug.cgi?id=2674


Andrei