## With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

No credit card required

# Computing Sums and Products

## Problem

You need to sum or multiply functions of numbers contained in a node set.

## Solution

The abstract form of sum for processors that support tail-recursive optimization is as follows:

```<xsl:template name="math:sum">
<!-- Initialize nodes to empty node set -->
<xsl:param name="nodes" select="/.."/>
<xsl:param name="result" select="0"/>
<xsl:choose>
<xsl:when test="not(\$nodes)">
<xsl:value-of select="\$result"/>
</xsl:when>
<xsl:otherwise>
<!-- call or apply template that will determine value of node
unless the node is literally the value to be summed -->
<xsl:variable name="value">
<xsl:call-template name="some-function-of-a-node">
<xsl:with-param name="node" select="\$nodes[1]"/>
</xsl:call-template>
</xsl:variable>
<!-- recurse to sum rest -->
<xsl:call-template name="math:sum">
<xsl:with-param name="nodes" select="\$nodes[position(  ) != 1]"/>
<xsl:with-param name="result" select="\$result + \$value"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>```

Two techniques can handle a large number of nodes in the absence of tail-recursive optimization. The first is commonly called `divide and conquer`. The idea behind this technique is to reduce the amount of work by at least a factor of two on each recursive step:

`<xsl:template name="math:sum-dvc"> <xsl:param name="nodes" select="/.."/> <xsl:param name="result" select="0"/> <xsl:param name="dvc-threshold" select="100"/> <xsl:choose> <xsl:when test="count(\$nodes) &lt;= \$dvc-threshold"> <xsl:call-template ...`

## With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, interactive tutorials, and more.

No credit card required