In one form or another I encounter the following question often (posed, here, in pseudo-code):
String myString = "Hello"
someObject.stringProperty = myString
myString = "World"
Why doesn't someObject.stringProperty now equal "World"?
There seems to be confusion about the role the following statement plays in the explanation of why this is the case:
Strings are Immutable
What do you think?
If you think the statement doesn't apply, I'd ask you this: In a language where strings were mutable, and the assignment operator mutated their actual value (instead of simply changing the reference), would your answer still make sense?
EDIT:
OK, I feel the need to clarify some things:
I'm not confused about how strings, references, or assignments work. I'm perfectly clear on this topic. I'm not asking how strings work. I'm asking "What role does string immutability play in the explaination of string references to developers". We can skip the Ad-Hominem attacks that I must be confused.
I'm looking for a logically rigorous answer for the developer asking the cited question which doesn't contain, or pre-suppose, the immutability of strings.
A categorization of the existing arguments:
String Immutability has nothing to do with it because the references are changing, not the values of the strings
This answer pre-supposes the exact fact I'm asking about.
Assignment means assignment of references not assignment of values
Again, this pre-supposes the exact fact I'm asking about. There is no reason this must be the case for strings. It simply is the case for strings for performance and other reasons.
The role played by the statement in the explanation depends on the explanation itself. It could be harmful or useful, depending on the rest of the explanation.
Personally I wouldn't use that statement until fairly late in the explanation (at least these days). The immutability of strings just gets in the way somewhat - as it does with parameter passing explanations. I'd start with an explanation using a mutable class, like this:
House x = new House(Color.Green); // The has a green front door
House y = x;
x = new House(Color.Red);
Console.WriteLine(y.FrontDoorColor); // Still green!
Here I would explain that x
and y
are like pieces of paper with the addresses of houses on. The assignment in the second line doesn't copy a house - it copies the address of a house. The assignment on the third line doesn't change the color of the front door on the first house - it creates a new house, then rubs out the address on the first piece of paper (x
), and writes the new address on. This doesn't change anything about the first house, or the second piece of paper (y
).
I'd then produce a second example:
House x = new House(Color.Green); // The has a green front door
House y = x;
x.FrontDoorColor = Color.Red; // Repainting a front door
Console.WriteLine(y.FrontDoorColor); // Red!
This time there's only one house - if I paint the door of a house and you come to see it with the address I'd given you earlier, you'll see the front door is now red.
So far, so good. Now I could go back to the original example and say that it already looks like the first house snippet rather than the second one, so it behaves the same way. I can then say that string immutability means you can't even write code that looks like the second house example but using strings. So string immutability wouldn't have been immediately relevant to the explanation of the existing code, but it would still have appeared in the same answer.
(I'd also have to point out that although references behave like real-world addresses, I'm not claiming that they're the same as "memory addresses" or pointers. They don't have to be. I'm using the term in a strict analogy to the real world, and that's all. It's a downside of the example, but I don't think it does too much harm.)
I might then also talk about value types, and consider what would have happened if House
had been a value type - as well as discouraging mutable value types.
To know whether or not my answer would still be relevant in a language with mutable strings, we'd need to know more about how string literals behaved. A language which was the same as C# in every way other than the mutability of strings would be an awful language, as you could write:
// Hypothetical bad language
string x = "dog";
x.MutateTo("cat");
Console.WriteLine("dog"); // Prints cat!
That clearly wouldn't be desirable, so presumably the behaviour of string literals would have to change. You also talk about possible changes to the meaning of the assignment operator, etc... it's hard to make concrete statements about a hypothetical language without knowing exactly how it behaves.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With