xtend

Inconsistency between pop and peek in a Stack: looking for an explanation


I have a program which uses a stack of sets of elements. The context here does not really matter. The code contains the following instructions:

val last = current_stack.pop
current_stack.peek.addAll(last)

At some point, I factored them as followed:

current_stack.peek.addAll(current_stack.pop)

To my surprise, the program behaved differently.

Does anybody have an explanation for this difference in behaviour?


Solution

  • It looks like xtend just compiles down to Java, so assuming that this translation is relatively straightforward (and doens't reorder parts of the expression), let's take a look at the equivalent Java:

    var last = current_stack.pop()
    current_stack.peek().addAll(last)
    
    // vs
    
    current_stack.peek().addAll(current_stack.pop())
    

    The java spec generally says that things are operated left to right, outside of things like parenthesis and operator precedence. For method invocation specifically, section 15.12.4 (JLS 21) says:

    At run time, method invocation requires five steps. First, a target reference may be computed. Second, the argument expressions are evaluated. …

    Here, the target reference is the object that comes from current_stack.peek(). Per the Java spec, this gets evaluated before the argument expressions — and in particular, in your second example, it gets evaluated before current_stack.pop().