If you've wondered why VW 7 made strings immutable, read this explanation of the concept by Andy Bowers of Object-Arts:
The literal String object that contained the characters ($s $m $a $l $l $t $a $l $k) is still there it is just that you have replaced the first indexed element of the object with $S. Then anything that referred to that String will now be referring to the new form, i.e. 'Smalltalk'.
So in LearningWorks, and earlier versions of some modern Smalltalks, you could try this:
string1 := 'smalltalk'.
string2 := string1.
string1 at: 1 put: $S.
string1 "Display it" -> 'Smalltalk'
string2 "Display it" -> 'Smalltalk'
While it looks like two variables, string1 and string2 have been oddly modified by this seemingly innocous act of modifying one of them this is not really the case. The key point is that Smalltalk treats variables differently from other languages. I only really "got" this point originally when someone explained that Smalltalk variables don't actually contain the object data (as they do in C++ for eg.) but actually they are "slots" that hold pointers to their objects. So effectively, Smalltalk variables are a bit like references in C++ (if that helps). So in the example above, string1 and string2 are holding a reference to the same object (the literal string 'smalltalk').
You might then wonder why modern implementations have made the modification of literal strings illegal. Well an example from early Dolphin Smalltalk might serve to illustrate this:
You may already know that you can use the #, message to concatenate one or
more Strings together (in fact you can use this message to concatenate any
sequenceable collections).
string1 := 'Smalltalk', ' is ', 'Great'.
However, if you take a look at the implementation of the #, message in SequenceableCollection then you'll see that, because it has to take a copy of the source string each time, then this might become rather inefficient for a large number of concatenations. So, most of the time, you'll be advised to use Streams when concatenating large amounts of text. This is how you do it:
stream := WriteStream on: String new.
stream
nextPutAll: 'Smalltalk';
nextPutAll: ' is ';
nextPutAll: 'Great'.
string1 := stream contents.
This may seem a rather long-winded procedure to tag a few strings together but, trust me, it's not really that bad in practice. Anyway, the point of this anecdote is that the above is almost the same as:
stream := WriteStream on: ''.
stream
nextPutAll: 'Smalltalk';
nextPutAll: ' is ';
nextPutAll: 'Great'.
string1 := stream contents.
And we found that several of the Dolphin developers used this form and got into a terrible mess. To be honest, I'm not sure it was their fault since I think that some early Smalltalk texts may have suggested it. So, what is wrong with creating a WriteStream on a literal empty string? Well, possibly nothing in some Smalltalk implementations. However, when we were designing Dolphin we took a leaf out of IBM Smalltalk's book and decided that it would be a good idea to share identical literal strings wherever possible. So, if you use the same literal string in more than one place in a method we only create one instance of the string and both places that use it share the same object. We also discovered that in the entire image there were initially a lot of empty literal string ('') objects. Hence, we made the Dolphin compiler, when it saw '' inside some Smalltalk source, always refer the same single instance of THE empty literal string (i.e. there is only one empty literal string object in the entire image).
This means that, if you did a (WriteStream on: ''), you would be writing over the top of the contents of the single empty literal string. This in turn meant that, if you ran the above code, every reference to an empty string in the entire system would suddenly turn into a reference to "Smalltalk is Great". Although most of our users would have agreed with the general sentiment of this phrase, few who tried the above code snippet would have agreed with it when their code browsers suddenly started filling the contents of empty methods with "Smalltalk is Great"!!
Anyway, the result is that Dolphin now throws an "Attempt to update read-only object" exception if any attempt is made to modify a literal string. I believe that the recent change to VisualWorks to throw an exception in similar circumstances now brings all the mainstream Smalltalks into line with one another.
I hope this helps rather than hinders....
Best Regards,
Andy Bower
Object Arts Ltd.