- From: Dimitre Novatchev <dnovatchev@gmail.com>
- Date: Wed, 12 Mar 2025 09:01:12 -0700
- To: Michael Kay <mike@saxonica.com>
- Cc: Christian Grün <cg@basex.org>, "public-xslt-40@w3.org" <public-xslt-40@w3.org>
- Message-ID: <CAK4KnZdTWvVoLFC4DkDdv+ZXKJ5K=Yq-6mqUKphpWJU+rp8w6g@mail.gmail.com>
> We can probably get a long way if we treat fn:for-each as primitive,
Actually, *fn:for-each* can be expressed as a *fold*. *Folds* and
*fn:numbered-items* could be the only primitives.
Here is a code example, where $forEach is defined in 6 lines. Watch how
much is accomplished in this pure XPath 3 code:
*let $numberedItems := function($input as item()*)*
* { for-each-pair(1 to count($input), $input, function($n,$it){[$n,
$it]})},*
*$forEach := function($input as item()*, *
* $action as function(item(), xs:integer) as
item()*)*
* {*
* fold-left($numberedItems($input), (), function($accum as item()*,
$current as item())*
* { ($accum, $action($current(2), $current(1)))}*
* )*
* }*
* return*
* (*
* $forEach(1 to 5, function($x) {2 * $x}),*
* $forEach(("Paris", "London", "Washington"), function($city, $pos)
{$city || '-' || (2 * $pos)})*
* )*
This could be even more simpler if we had the Record in XPath - then
fn:numberedItems would return a sequence of records and not of arrays.
Here is a screenshot executing this with BaseX:
[image: image.png]
Look how much we accomplish with just a few lines of code.
Thanks,
Dimitre.
On Wed, Mar 12, 2025 at 4:42 AM Michael Kay <mike@saxonica.com> wrote:
> We can probably get a long way if we treat fn:for-each as primitive,
> then we have for example
>
> declare fn:filter($input, $predicate) {
> fn:for-each($input, fn($item, $pos) { if ($predicate($item, $pos)) {
> $item } })
> }
>
> and then we can define for-each using head-tail recursion.
>
> That's analogous to what we've done with maps where we treat iterate-map()
> as the primitive accessor.
>
> Michael Kay
>
>
> On 12 Mar 2025, at 11:15, Michael Kay <mike@saxonica.com> wrote:
>
> As with everything else in the specification, the formal equivalents are
> designed to provide a contract between implementators and users, which both
> parties should be capable of understanding.
>
> The ideal is that everything should be defined directly or indirectly in
> terms of primitives in the data model. We should avoid the "formal
> equivalents" becoming circular, and we should try to avoid reliance of
> constructs that don't themselves have a formal equivalent - which includes
> things like the "!" operator and FLWOR expressions. In an ideal world we
> would define a core language and everything else would be defined in terms
> of that core.
>
> With the array functions I did actually check that all the formal
> equivalents passed the tests and had no dependencies on array operations
> other than the primitives in the data model. For sequence functions we're
> not there yet.
>
> Michael Kay
>
> On 12 Mar 2025, at 10:36, Christian Grün <cg@basex.org> wrote:
>
> > In most case it's easy enough, for example fn:filter becomes
> >
> > fold-left($input ! {'item': ., 'pos': position()},
> > (),
> > fn($result, $pair) {
> > if ($predicate($pair?item, $pair?pos))
> > then ($result, $pair?item)
> > else $result
> > })
>
> …and the function call would need to be followed by an ?item lookup.
>
> One question may be who is supposed to be the recipient of the equivalent
> code. If we want to address users, I think that we should focus on
> simplicity. For fn:filter, a FLWOR expression may be much easier to digest:
>
> for $item at $pos in $input
> where $predicate($item, $pos)
> return $item
>
> Next, many functions (including fn:index-of or fn:avg) don’t seem to have
> a formal counterpart. Maybe it’s not required in all cases? Folds are a
> good example: For advanced users, it is obvious what it does, and there
> will be no need to digest the equivalent code. For others, the main
> challenge is to understand the very principle, and tutorials will probably
> be more helpful than a concise recursive function.
>
>
>
>
Attachments
- image/png attachment: image.png
Received on Wednesday, 12 March 2025 16:01:29 UTC