Discussion:
[xquery-talk] function declaration vs expression
W.S. Hager
2016-03-14 13:48:29 UTC
Permalink
Hello,

What is the difference between a function declaration and a function
expression in a variable declaration, eg:

declare variable $local:id := function($x) { $x }

and why does it exist?
--
W.S. Hager
Lagua Web Solutions
http://lagua.nl
Ghislain Fourny
2016-03-14 14:18:24 UTC
Permalink
Hi WS,

Higher-order functions were added in XQuery 3.0 so that you can build
them dynamically (using closures) and pass them as parameters like any
other items.

I see little benefit in defining your function as a variable
declaration with an inline function expression vs. a static function
declaration such as

declare function local:id($x) {
$x
};

You can reference the former with $local:id and the latter with
local:id#1 to make them flow around as function items. You can call
the former with $local:id($x) and the latter with local:id($x). The
former has no name, the latter has a name (local:id).

When you need a function that dynamically depends on the value of a
variable at runtime, however, you will need to use inline function
expressions. Variables in scope will be added to the closure of the
created function item.

I hope it helps!

Kind regards,
Ghislain
Post by W.S. Hager
Hello,
What is the difference between a function declaration and a function
declare variable $local:id := function($x) { $x }
and why does it exist?
--
W.S. Hager
Lagua Web Solutions
http://lagua.nl
_______________________________________________
http://x-query.com/mailman/listinfo/talk
_______________________________________________
***@x-query.com
http://x-query.com/mailman/listinfo/talk
W.S. Hager
2016-03-15 05:48:57 UTC
Permalink
Ah right, you can't overload a variable of course.
Post by Ghislain Fourny
Hi WS,
Higher-order functions were added in XQuery 3.0 so that you can build
them dynamically (using closures) and pass them as parameters like any
other items.
I see little benefit in defining your function as a variable
declaration with an inline function expression vs. a static function
declaration such as
declare function local:id($x) {
$x
};
You can reference the former with $local:id and the latter with
local:id#1 to make them flow around as function items. You can call
the former with $local:id($x) and the latter with local:id($x). The
former has no name, the latter has a name (local:id).
When you need a function that dynamically depends on the value of a
variable at runtime, however, you will need to use inline function
expressions. Variables in scope will be added to the closure of the
created function item.
I hope it helps!
Kind regards,
Ghislain
Post by W.S. Hager
Hello,
What is the difference between a function declaration and a function
declare variable $local:id := function($x) { $x }
and why does it exist?
--
W.S. Hager
Lagua Web Solutions
http://lagua.nl
_______________________________________________
http://x-query.com/mailman/listinfo/talk
--
W.S. Hager
Lagua Web Solutions
http://lagua.nl
Leo Studer
2016-04-26 10:02:13 UTC
Permalink
Hello Cracks ;-)

I need to find the most occurring incidence, lets say the color that occurs most out of

<colors>
<color>red</color>
<color>green</color>
<color>blue</color>
<color>red</color>
<color>green</color>
<color>green</color>
<color>red</color>
<color>blue</color>
<!-- .... -->
</colors>


Here my first solution

(for $color in distinct-values(//color)
order by count(//color[. eq $color]) descending
return $color)[1]

Problem: red and green have both 3 occurrences.

This works but looks horrible

for $max in max(for $color in distinct-values(//color) return count(//color[. eq $color])),
$color in distinct-values(//color)
return
if (count(//color[. eq $color]) eq $max) then $color else ()


Any better suggestions?

Thanks in advance
Leo
Christian Grün
2016-04-26 10:17:04 UTC
Permalink
Hi Leo,

here’s one more solution. It is not much shorter than yours, but may
be a bit more readable:

let $cols :=
for $colors in //color
group by $value := $colors/data()
return <color count="{ count($colors) }" value="{ $value }"/>
let $max := max($cols/@count)
return $cols[@count = $max]/@value/data()

I think that in every case the values need to be accessed at least
twice, because we’ll first need to find out what is the actual maximum
count, and then need to look for all values matching that maximum.

Hope this helps,
Christian
Post by Leo Studer
Hello Cracks ;-)
I need to find the most occurring incidence, lets say the color that occurs most out of
<colors>
<color>red</color>
<color>green</color>
<color>blue</color>
<color>red</color>
<color>green</color>
<color>green</color>
<color>red</color>
<color>blue</color>
<!-- .... -->
</colors>
Here my first solution
(for $color in distinct-values(//color)
order by count(//color[. eq $color]) descending
return $color)[1]
Problem: red and green have both 3 occurrences.
This works but looks horrible
for $max in max(for $color in distinct-values(//color) return
count(//color[. eq $color])),
$color in distinct-values(//color)
return
if (count(//color[. eq $color]) eq $max) then $color else ()
Any better suggestions?
Thanks in advance
Leo
_______________________________________________
http://x-query.com/mailman/listinfo/talk
_______________________________________________
***@x-query.com
http://x-query.com/mailman/l
Christian Grün
2016-04-26 10:35:34 UTC
Permalink
And two another solutions, taking advantage of maps:

The more readable one:

let $map := map:merge(
for $color in //color
group by $value := $color
return map { $value: count($color) }
)
let $max := max($map?*)
return map:for-each($map, function($color, $value) {
if($value eq $max) then $color else ()
})

The more cryptical (and not that efficient) one:

let $m := map:merge(
for $v in distinct-values(//color)
return map { $v: count(//color[. eq $v]) }
)
return map:keys($m)[$m(.) = max($m?*)]



On Tue, Apr 26, 2016 at 12:17 PM, Christian Grün
Post by Christian Grün
Hi Leo,
here’s one more solution. It is not much shorter than yours, but may
let $cols :=
for $colors in //color
group by $value := $colors/data()
return <color count="{ count($colors) }" value="{ $value }"/>
I think that in every case the values need to be accessed at least
twice, because we’ll first need to find out what is the actual maximum
count, and then need to look for all values matching that maximum.
Hope this helps,
Christian
Post by Leo Studer
Hello Cracks ;-)
I need to find the most occurring incidence, lets say the color that occurs most out of
<colors>
<color>red</color>
<color>green</color>
<color>blue</color>
<color>red</color>
<color>green</color>
<color>green</color>
<color>red</color>
<color>blue</color>
<!-- .... -->
</colors>
Here my first solution
(for $color in distinct-values(//color)
order by count(//color[. eq $color]) descending
return $color)[1]
Problem: red and green have both 3 occurrences.
This works but looks horrible
for $max in max(for $color in distinct-values(//color) return
count(//color[. eq $color])),
$color in distinct-values(//color)
return
if (count(//color[. eq $color]) eq $max) then $color else ()
Any better suggestions?
Thanks in advance
Leo
_______________________________________________
http://x-query.com/mailman/listinfo/talk
_______________________________________________
***@x-query.com
http:/

Continue reading on narkive:
Loading...