www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - how would D be different if string were const(char)[]?

reply "Daniel Davidson" <nospam spam.com> writes:
If it would be no different then why prefer immutable(char)[] for 
string?
Oct 17 2013
next sibling parent reply "Dicebot" <public dicebot.lv> writes:
On Thursday, 17 October 2013 at 13:08:18 UTC, Daniel Davidson 
wrote:
 If it would be no different then why prefer immutable(char)[] 
 for string?
Allocation-free slicing would have been illegal/unsafe then as someone could have possibly modified underlying chars via mutable reference.
Oct 17 2013
next sibling parent "Dicebot" <public dicebot.lv> writes:
Small example, this is valid D:

void main()
{
    char[] mut = "aaa".dup;
    const(char)[] str = mut;
    mut[1] = 'b';
    assert (str == "aaa"); // oops
}
Oct 17 2013
prev sibling parent reply "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Thursday, October 17, 2013 15:18:19 Dicebot wrote:
 On Thursday, 17 October 2013 at 13:08:18 UTC, Daniel Davidson
 
 wrote:
 If it would be no different then why prefer immutable(char)[]
 for string?
Allocation-free slicing would have been illegal/unsafe then as someone could have possibly modified underlying chars via mutable reference.
It wouldn't have to be illegal, and there's nothing unsafe about it. You can slice fully mutable arrays as much as you like without allocating any memory, and it's perfectly safe. However, you can't rely on the elements of a const array not being modified (because a mutable reference to the same data could modify it), and you can't share it across threads (as unlike immutable, const is not implicitly shared). So, dealing with strings if they were const(char)[] would probably be more bug-prone, and you'd be forced to dup your strings far more often in order to guarantee that they weren't being altered by a mutable reference somewhere. On top of that, you really wouldn't gain anything. So, it would definitely be a bad idea. Defaulting to immutable(char)[] makes a lot of sense, and you can still use const(char)[] or char[] if you want to, so it's not like it's particularly limiting either. - Jonathan M Davis
Oct 17 2013
parent reply "Dicebot" <public dicebot.lv> writes:
Well, yeah. it is memory safe but you can't slice a string and be 
sure its value won't change silently - comparable semantical 
safety disaster IMHO.
Oct 17 2013
parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Thursday, October 17, 2013 18:50:25 Dicebot wrote:
 Well, yeah. it is memory safe but you can't slice a string and be
 sure its value won't change silently - comparable semantical
 safety disaster IMHO.
Yeah. You have to be concerned about whether the values change, which makes the string situation considerably worse. But you have to be careful with the term "safe," because around here that almost always means memory safety. - Jonathan M Davis
Oct 17 2013
prev sibling parent reply "Meta" <jared771 gmail.com> writes:
On Thursday, 17 October 2013 at 13:08:18 UTC, Daniel Davidson 
wrote:
 If it would be no different then why prefer immutable(char)[] 
 for string?
Strings are immutable in quite a few other languages. Ex: Java, Python. I found this old article written by Walter: http://www.drdobbs.com/architecture-and-design/invariant-strings/228700475
Oct 17 2013
parent reply "Daniel Davidson" <nospam spam.com> writes:
On Thursday, 17 October 2013 at 18:28:31 UTC, Meta wrote:
 On Thursday, 17 October 2013 at 13:08:18 UTC, Daniel Davidson 
 wrote:
 If it would be no different then why prefer immutable(char)[] 
 for string?
Strings are immutable in quite a few other languages. Ex: Java, Python. I found this old article written by Walter: http://www.drdobbs.com/architecture-and-design/invariant-strings/228700475
True and I believe they do it without an immutable keyword. I'm not questioning the value of a non-mutable type, just trying to get to the heart of why the keyword immutable is preferred over const in this example. Dicebot clarified it - essentially it is because sharing can creep in before it gets settled into a const(char)[] context. And once sharing has potentially happened you can't undo it except for transitive deep copy. Had D gone with: struct String { const(char)[] s_; this(char[] s) { s_ = s.dup; } } and not allowed any modification of elements you would still have immutable without the keyword. Granted, it would not be efficient so I see the benefit. Strings/slices have sharing. Can the same issue/benefit occur with primitives? Would you ever have a need for `immutable(int)` over `const(int)`?
Oct 17 2013
next sibling parent reply "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Thursday, October 17, 2013 21:17:37 Daniel Davidson wrote:
 Strings/slices have sharing. Can the same issue/benefit occur
 with primitives? Would you ever have a need for `immutable(int)`
 over `const(int)`?
For value types, there's no real difference between immutable and const. Because they're value types, you can't have mutable references to them. The differences between const and immutable only really come into play once you're dealing with reference types, because then you can end up with differently qualified references to the same data. - Jonathan M Davis
Oct 17 2013
parent "Dicebot" <public dicebot.lv> writes:
On Thursday, 17 October 2013 at 19:53:34 UTC, Jonathan M Davis 
wrote:
 For value types, there's no real difference between immutable 
 and const.
 Because they're value types, you can't have mutable references 
 to them. The
 differences between const and immutable only really come into 
 play once you're
 dealing with reference types, because then you can end up with 
 differently
 qualified references to the same data.
It is important to make clarify that this is true only for directly accessible value types. Once any single level of indirection is in question, `const` stops giving any guarantees. This is exactly the case for `const(char)[]` vs `immutable(char)` - `const(char)` itself is a value type but pointer to `const(char)` can also store pointer to mutable `char`.
Oct 17 2013
prev sibling parent "Meta" <jared771 gmail.com> writes:
On Thursday, 17 October 2013 at 19:17:38 UTC, Daniel Davidson 
wrote:
 True and I believe they do it without an immutable keyword.
They do, but it's a special case, as opposed to D.
 I'm not questioning the value of a non-mutable type, just 
 trying to get to the heart of why the keyword immutable is 
 preferred over const in this example.
As Dicebot said, NOBODY can modify immutable, while they can modify const. YOU are the only one that can't modify const. It could change right under you at any time.
 Dicebot clarified it - essentially it is because sharing can 
 creep in before it gets settled into a const(char)[] context. 
 And once sharing has potentially happened you can't undo it 
 except for transitive deep copy.

 Had D gone with:

 struct String {
    const(char)[] s_;
    this(char[] s) { s_ = s.dup; }
 }

 and not allowed any modification of elements you would still 
 have immutable without the keyword. Granted, it would not be 
 efficient so I see the benefit.
That'd be a special case like in other languages, which isn't necessary in D because of immutable.
 Strings/slices have sharing. Can the same issue/benefit occur 
 with primitives? Would you ever have a need for 
 `immutable(int)` over `const(int)`?
Only if there's indirection, e.g., int vs. pointer to int.
Oct 17 2013