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?
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()
.