Bug #3106
closedProblems applying fold-left() to random-number-generator()
100%
Description
The query
fold-left(1 to 10, random-number-generator(), function($z, $i){ head($z)('next')(), tail($z), head($z)('number')}) => tail()
ought to give a sequence of random numbers. It is failing in different ways in 9.7 and 9.8.
In 9.7 the final call to tail() returns an empty sequence; the result of fold-left() is a sequence containing a single item, the random-number-generator itself (a HashTrieMap).
In 9.8 the query crashes, saying
java.lang.IllegalStateException: A LazySequence can only be read once
at net.sf.saxon.om.LazySequence.iterate(LazySequence.java:52)
at net.sf.saxon.expr.VariableReference.iterate(VariableReference.java:525)
at net.sf.saxon.expr.TailExpression.iterate(TailExpression.java:135)
Updated by Michael Kay over 7 years ago
- Status changed from New to Resolved
- Applies to branch deleted (
9.7) - Fix Committed on Branch 9.8 added
In the 9.7 case: user error. The query is generating the correct results but I failed to display them correctly.
Minor issue spotted: HashTrieMap.isTrustedResultType() returns false; this leads to unnecessary type checking of the result. It can safely return true, since the declared result type is ANY_SEQUENCE and the result will always satisfy this.
For 9.8, it is failing because arguments to a system function call (in this case the outermost call on fold-left) are passed as a LazySequence object, the contract being that the implementation of the system function will only read this sequence once. The implementation of fold-left() is not honouring this contract, because it passes the second argument "as is" to a user-written function which is not subject to this contract.
Fixed for 9.8 only.
Updated by Michael Kay over 7 years ago
- Applies to branch 9.7 added
- Fix Committed on Branch 9.7 added
Running some further tests, I tried increasing the first argument from (1 to 10) to read (1 to 1000). This leads to a StackOverflow, because the function accumulates a very deeply nested LazySequence, and the final evaluation of this LazySequence is recursive, which blows the stack. So I'm adding a patch which prevents the sequence becoming too deep: fold-left turns it into a grounded sequence every 20 iterations or so, providing a compromise between use of heap memory and excessive recursion.
Updated by O'Neil Delpratt about 7 years ago
- Status changed from Resolved to Closed
- % Done changed from 0 to 100
- Fixed in Maintenance Release 9.7.0.15 added
Bug fix applied to the Saxon 9.7.0.15 maintenance release
Updated by O'Neil Delpratt almost 7 years ago
- Fix Committed on Branch trunk added
- Fix Committed on Branch deleted (
9.8)
Please register to edit this issue