You may be interested in my https://github.com/rhdunn/xquery-intellij-plugin/blob/master/docs/XQuery%20I... document. It is the result of previous investigations in supporting static type analysis in my XQuery plugin.
Thanks, I’ll definitely have a look at your document.
In BaseX, we don’t have union types; apart from that, our static typing system should be close to complete (if some types in the query plan should indicate otherwise, feedback is welcome). For example, we are iteratively computing the type of built-in higher-order functions at compile time. The static type of the following function is xs:decimal+:
fold-left(1 to 123, 4.5, function($tmp, $curr) { ($curr, $tmp) })
And the static type of the next expression is xs:short+, not xs:integer+ as one might guess (the type derived from the actual types of the input arguments, which will never yield an xs:integer result type):
fold-left((1 to 20) ! xs:byte(.), (), function($tmp, $curr) { $tmp, if($curr instance of xs:byte) then xs:short($curr) else xs:integer($curr) })
One missing link is that the static type is not always propagated to the result (i.e., to the internal result representation, which can be a plain untyped array of typed items, in particular if the result is generated by untyped iterators). I think I’ve found a good trade-off between performance and better runtime typing. In future, the intersection of the type of the original expression and the resulting type will be assigned to the resulting value instance.