qt4cg / qtspecs

QT4 specifications
https://qt4cg.org/
Other
28 stars 15 forks source link

[XPath] Functions symmetric to `head()` and `tail()` for sequences and arrays #97

Closed dnovatchev closed 1 year ago

dnovatchev commented 2 years ago

In Xpath 3.1 we already have head(), tail(), and last()

But there is no function that produces the subsequence of all items of a sequence except the last one. There exists such a function in other programming languages. For example, in Haskell this is the init function.

And the last() function isn't the symmetric opposite of head() -- it doesn't give us the last item in a sequence, just its position. So we need another function: fn:heel() for this.

fn:init($sequence as item()*) as item()*

fn:heel($sequence as item()*) as item()?

init($seq) is a convenient shorthand for subsequence($seq, 1, count($seq) -1)

heel($seq) is a convenient shorthand for slice($seq, -1)

Examples:

fn:init(('a', 'b', 'c')) returns 'a', 'b'

fn:init(('a', 'b')) returns 'a'

fn:init('a') returns ()

fn:init(()) returns ()

fn:heel('a', 'b', 'c') returns 'c'

('a', 'b', 'c') => init() => heel() returns 'b'

It makes sense to have fn:init() and fn:heel() defined on arrays, too.

array:init($array as array(*)) as array(*)

array:heel($array as array(*)) as item()*

Examples:

array:init([1, 2, 3, 4, 5]) returns [1, 2, 3, 4]

array:init([1]) returns []

array:heel([1, 2, 3, (4, 5)]) returns (4, 5)

array:heel([()]) returns () (the empty sequence)

array:init([]) produces error

array:heel([]) produces error

[1, 2, 3, (4, 5)] =>array:heel() => heel() returns 5

I would challenge anyone to re-write the last example in understandable way using fn:slice() 💯

benibela commented 2 years ago

If we wanted, we could check if other programming languages provide an ever better term.

In another project, I settled for left/right with/of first/last to get subsequences.

left returns elements from the start, right returns element till the end. with is inclusive, of is exclusive. Now this gives a subsequence, so there is another end somewhere in the middle of the origin sequence, and first counts this middle end from the start, and last counts it from the end.

It would match the functions like this:


head($x)       ~~  left-with-first($x, 1)

tail($x)       ~~  right-of-first($x, 1)

init($x)       ~~  left-of-last($x, 1)

heel($x)       ~~  right-with-last($x, 1)
michaelhkay commented 2 years ago

If we didn't already have insert-before, remove, parse-xml, normalize-space, reverse, resolve-uri, sort, translate, replace, tokenize, then I could understand an objection to using an imperative verb. But it's too late for that.

And if imperative verbs are allowed, then there can be no objection to truncate because it expresses precisely what this function does.

dnovatchev commented 2 years ago

If we didn't already have insert-before, remove, parse-xml, normalize-space, reverse, resolve-uri, sort, translate, replace, tokenize, then I could understand an objection to using an imperative verb. But it's too late for that.

And if imperative verbs are allowed, then there can be no objection to truncate because it expresses precisely what this function does.

Disagree. In this specific group of functions 3 of the 4 functions all have noun-names. So, what is so difficult to keep the naming of this group "clean" and find a last 4th noun that is suitable? And not to mention that we have quite a lot of native English speakers here ...

ChristianGruen commented 2 years ago

So, what is so difficult to keep the naming of this group "clean" and find a last 4th noun that is suitable?

Remember that we started with init. I'm not sure if it’s justified to call it a word at all, let alone a noun.

If we hadn't tail, remove-first and remove-last would be other choices.

michaelhkay commented 2 years ago

I'm not a native English speaker, but I have acquired a reasonable grasp of the language over the last 65 years, and I'm not aware of any noun that intuitively describes the thing that's left over when you remove its far end.

You're thinking of a group of four functions as being in some way homogenous. I don't share that perspective. I see truncate() more as a special case of remove(). I'd be quite happy to call it remove-last().

michaelhkay commented 2 years ago

PR #250 has been raised.

ndw commented 1 year ago

Closed by #250.