Before we dive into the technical details of environments, stores, and stack allocation, we should take some time to go over the concepts of static allocation, stack allocation, and heap allocation, and to look at some typical examples of where each would be used.
Comments on the Tucker and Noonan book:
Page 120: Figure 5.1 and the accompanying text assume that the heap size, and hence the value of h, remains fixed, with the stack growing up toward the heap. More realistically the heap can also grow down toward the stack, by decreasing h. For simplicity, we will stick (for now, anyhow) with the idea of a fixed-sized heap.
Page 121: You should be aware that a memory is often called a store. This is the British term even with reference to hardware, but for some reason has become more internationally dominant in programming language semantics than in hardware.
The definition of a state as a product of an environment and a memory is faulty in two regards. First, what is needed is the ordered pair (γm, μ), not the cartesian product of the two sets. Second, the state also needs to contain a third element, the stack pointer a.
Pages 121-122: The idea that an environment can contain two bindings for the same name reflects a bug later in the chapter. In fact, there is no reason why environments shouldn't be functions, just like memories are, with only one entry for each name. This eleminates the need for "max" in the defintion of γm(v) on page 121 and also the use of ordinary set union, rather than overriding union on page 122.
Page 122: The definitions of allocate and deallocate need touch-ups to reflect the earlier comments, and also are each missing the equation σ=(γ,μ,a).
The static link and dynamic link aren't actually needed for anything we will be doing, so we will simply eliminate them from our discussion. (That will also avoid the need to correct technical errors concerning them.)
Pages 123-124: We should achieve better clarity about the difference between static and dynamic scoping. Note in particular that there is no reason why a language without nested procedures necessarily would have "a strictly static scoping strategy," contrary to page 124.
Page 125: The reference to μ(0) in the second paragraph should be μ0. The set of pairs shown immediately afterward is μ0; the full state σ0 should also contain the empty environment and (I would add) the value of 0 from the allocation variable a. (Keep in mind throughout this book that Tucker and Noonan are misusing the cross-product operator to mean pairing.)
At the bottom of the page, σm is defined incorrectly. If the call to m is done in state σ=(γ, μa, a), then σm=allocate(m.params,m.locals, (γg, μa, a)). That is, the environment should be based on γg, as in fact is indicated further down on the page, rather than being based on γ. Note also that the memory component of σ is μa, not μ. The last line on the page also needs to be corrected to show μa rather than μ(a).