Exercise 5.x1:
Suppose the following program (in extended Jay) were executed three
times: once using call-by-value, once using call-by-value-result, and
once using call-by-reference. What would be the value of
y
at the end of each execution? Explain your answers;
you may find diagrams useful for this purpose.
package PassTest { int y = 3; void p(int x){ y = 5; x = x + 1; } void main(){ p(y); } }
Exercise 5.x2: As discussed in class, the environments γA and γB on page 129 are incorrect. Instead of
γA = γmain ∪
{‹x, 4›, ‹y, 5›,
‹i, 6›, ‹j, 7›}
γB = γA ∪
{‹w, 8›, ‹j, 9›,
‹k, 10›}
the defining equations ought to be
γA = γg ∪
{‹x, 4›, ‹y, 5›,
‹i, 6›, ‹j, 7›}
γB = γg ∪
{‹w, 8›, ‹j, 9›,
‹k, 10›}
That is, each environment is formed from the global environment, not from the caller's environment. (I also show overriding union rather than regular union, so that the "max" operator isn't needed. This is a comparatively minor point.)
To help understand why this change is necessary, please answer the following questions about the book's incorrect version:
The last paragraph on page 129 makes reference to changing the
global variable i
. Which variable named i
would the body of B
really wind up changing, using the
book's environment? Why?
Another way of describing this is that the book's version winds up unintentionally implementing an alternative scoping rule. What is the name for that form of scoping?
In this example, how well does this alternative scoping rule wind up meshing with static typing? Explain.
Do exercise 5.8 on page 153.
Exercise 5.x3: Consider the following two nearly identical Java programs,
each of which uses an array of Integers, s
, as a stack,
with sp
serving the role of stack pointer. Each program
repeats 100 times the following two stages:
(1) push the Integers 0 up to 100000, (2) pop them all back off.
public class Bar { public static void main(String[] args){ Integer[] s = new Integer[100000]; int sp = 0; for(int i = 0; i < 100; i++){ for(int j = 0; j < 100000; j++){ s[sp++] = j; } while(sp > 0){ --sp; } } } }
public class Baz { public static void main(String[] args){ Integer[] s = new Integer[100000]; int sp = 0; for(int i = 0; i < 100; i++){ for(int j = 0; j < 100000; j++){ s[sp++] = j; } while(sp > 0){ s[--sp] = null; } } } }
Answer the following questions about these two programs:
Why might Bar be faster than Baz?
Why might Baz be faster than Bar?
By guessing which of these effects is larger, which of the two programs do you expect to be faster?
Which one actually is faster, and by how much?