The expression
for $i at $p in 1 to 5 return $p[last()]
returns 10 when it should return 5.
The reason lies in the strategy for evaluating last(). Saxon uses various strategies, but in this case the approach is to evaluate the base sequence twice, the first evaluation discards the results and merely counts how many items are present. For this purpose, every SequenceIterator that can iterate over a sequence of items is required to implement a method getAnother() that creates a clone of itself, positioned at the start of the sequence. For a "for" expression, the iterator used is a MappingIterator, which applies a specified MappingFunction to each item in the input sequence. This strategy relies on the MappingFunction itself being stateless - that is, calling it twice on the same input should return the same result. Unfortunately the MappingFunction used for a "for" expression with a positional variable is not stateless; it has the side-effect of incrementing the variable. In this example the mapping function is called 10 times so the positional variable ends up with the value 10.
A patch is being placed in Subversion. This uses a marker interface to identify a MappingFunction that maintains state information (of which this is currently the only example), allowing the MappingFunction to be cloned at the same time as the iterator itself is cloned.
Logged In: YES
user_id=251681
Originator: YES
Fixed in 9.0.0.3