johnson@uiucdcsp.cs.uiuc.edu (03/31/88)
It is pretty well known that literal arrays have the "wrong" behavior in Smalltalk, i.e. they do not behave like constants. To understand why literals behave the way they do, you need to understand the structure of a Smalltalk compiled method. A compiled method has an integer header, an array called the literal frame, and an array of byte-codes. The traditional implementation uses a tricky encoding to keep all these things in one array, but a compiled method has these three logical components. The header describes the number of arguments, temporaries, etc. The array of byte-codes is the executable code. The only part that is tricky to understand is the literal frame. The literal frame is used for all sorts of things. One of the most important is that it holds literal arrays, symbols, characters, etc. that are referenced by the method. There are special byte-codes to "push literal n" that allow the compiled method to retrieve objects stored in the literal frame. The literal frame is also used to hold selectors for messages and a few other odds and ends. When you compile a method that contains a literal array, the array is placed in the literal frame. Thus, when the executing method references the array, it just retrieves the pointer for it from the literal frame. If the program subsequently modifies the array, it will be modifying the very same array that is stored in the literal frame. Thus, the literal array should not be thought of as a constant. As has been suggested, the solution is to always copy the literal array first if you plan to modify it in the future. One problem is that it seems harder to remember to do this with strings, which suffer the same problem. One solution is to adapt a functional style of programming in which you try to minimize assignments. This is a good idea for many other reasons, as well. The implementation section of the blue book is must reading for anybody who wants to be a Smalltalk expert. Several parts of the language are defined by the implementation rather than for any theoretical reason. This is sad, but true.