2

1) What is difference between string and string literal

2) a book says 'zero' at: 1 put: $h will fail because literals are immutable but if I do 'zero' copy at: 1 put: $h works because copying a literal string produces another string which is not a literal. Confused!

Bhushan Lodha
  • 6,824
  • 7
  • 62
  • 100

3 Answers3

5

Imagine you have a method answering a literal string (literal means whose contents is written literally in source code)

MyClass>>constantString
    ^'foo'

Now, if this literal string is mutable, you can nastily perform this snippet

MyClass new constantString at: 1 put: $b.

Then every instance of MyClass will answer 'boo' to #constantString. Though, you can't understand why, because the source code still indicates 'foo'. Nasty...

Some Smalltalk dialects make those literal string immutable to avoid such accidental bad surprise. Some don't have virtual machine support for immutability and let the entire responsibility to the user.

aka.nice
  • 9,100
  • 1
  • 28
  • 40
  • Why do you need VM support for this? Why not just have a StringLiteral class that doesn't implement `#at:put`? – Philippe Marschall Aug 03 '12 at 05:26
  • Agree, also #basicAt:put:, and immutablility is guaranteed if the VM lacks mirror object:basicAt:put: and withArgs:executeMethod: . Personnally, I would prefer all String being immutable once constructed, that is immediately after messages like collect:, select: or WriteStream contents... If you want a statefull object, you should say so. – aka.nice Aug 03 '12 at 14:27
1
| a b |
a := b := 'foo'.
a == b. "=> true, so the identical string"
a at: 1 put: $b.
b "=> 'boo'

So in Squeak, and probably in Pharo, string literals are not immutable.

Other Smalltalks do support immutability, so perhaps string literals in those Smalltalks are indeed immutable.

Regarding copying, perhaps you're carrying assumptions over from other languages. 'foo' is a literal in the sense that there's syntax for creating a String, but really, 'foo' is just another object. In Squeak and Pharo these literals are just normal String instances, and so you are free to mutate them.

As the above snippet shows, that can lead to unexpected results, because if you change the first line to a := 'foo'. b := 'foo'. you still end up with the same result: Squeak quietly shares that literal, rather than making a new one with the same value.

Frank Shearar
  • 17,012
  • 8
  • 67
  • 94
1

The book is wrong. In squeak, strings are not immutable. Which book is that?

'zero' at: 1 put: $h; yourself. => 'hero'

'zero' copy at: 1 put: $h; yourself => 'hero'

Characters are immutable though. It would be funny if they weren't.

milan
  • 2,355
  • 2
  • 23
  • 38
  • actually book is general SmallTalk book and not particular to Squeak. I wanted to know how strings and string literals are different – Bhushan Lodha Jul 23 '12 at 00:53
  • Hmm, squeak Characters are mutable as well. the 'value' instance variable is protected in only assignment setValue:, but would not resist to instVarAt: 1 put: newValue. setValue: newValue value ifNotNil:[^self error:'Characters are immutable']. value := newValue. – aka.nice Jul 27 '12 at 16:44