If we're going to have a modifier argument that changes the behaviour then it should be a map, not a string, to make it extensible. But even then, I don't like having a modifier argument that changes the essence of what the function does quite so fundamentally.
I've been trying out a function fn:range that takes predicates for both the start and end of the range, with an options argument to say whether the start and end are inclusive or exclusive: you can see test cases here:
https://github.com/qt4cg/qt4tests/blob/master/fn/range.xml
But I'm not totally happy with it. After working through these use cases, I think it's probably better to rely on composing two separate functions
range-from($seq, matches(?, "a")) => range-to($seq, matches(?, "z")
and the question then is how to handle the inclusive/exclusive distinction. My original proposal was to have four functions, each taking a sequence and a predicate: items-before, items-until, items-from, items-after. In many ways I think that's a better solution. Perhaps changing the name to range-before, etc. It certainly better fits the design criterion that a function should do one simple job.
The reason I moved in the direction of fewer functions with more complex arguments was primarily the concern expressed about the fact that the functions are in a global namespace so it's hard to find simple function names that say clearly what each function does; the more specialised the function becomes, the more you have to give it a long-winded name.
Michael Kay
Saxonica