XSLT3.0への道(27) 閑話休題:無名関数で再帰する.

XSLT 2.0はxsl:functionが導入されて、これがXPathの中から呼び出せるのでずいぶんと便利になったものです.よくある関数の再帰でも、例えばxのn乗を求める場合、

    <xsl:function name="ahf:powerOfY" as="xs:integer">
        <xsl:param name="prmX" as="xs:integer"/>
        <xsl:param name="prmY" as="xs:integer"/>
        <xsl:choose>
            <xsl:when test="0 lt $prmY -1">
                <xsl:sequence select="$prmX * ahf:powerOfY($prmX, $prmY - 1)"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:sequence select="$prmX"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:function>

と書いて自分自身(ahf:powerOfY)を呼び出します.ではこれをXSLT 3.0のインライン関数で書いたらどうなるのか考えていたら訳がわからなくなってしまいました.xの2乗を求めるインライン関数なら、再帰はないので

 <xsl:variable name="powerOf2" as="function(*)" select="function($x as xs:integer) as xs:integer {$x * $x}"/>
 
 <xsl:variable name="x" as="xs:integer" select="3"/>
 <!-- ここでxの2乗を求め、xの値、結果の値をxsl:messageで表示します-->
 <xsl:message select="'x=', $x, ' xの2乗=', $powerOf2($x)"/>

で話はおしまいなのですが、再帰となると自身が無名関数なので呼び出すことができないのです.そこで日本のスタックオーバーフローに質問を投げてみたら速攻で回答が返ってきました.ビックリ!関数を引数に取る関数を作成し、その関数に処理をゆだねます.

XSLT 3.0で無名関数での再帰はどうのように記述するのでしょうか?

これを一発で書けと言われたら思わず「無理!」と言わざるを得ません.確かに実際の場面でいちいちインライン関数でこのような機能を実装することはないでしょうけれども、高階関数が導入されることにより、このようなことが「出来てしまう」のですからXSLT 3.0の言語の進化というものは恐ろしいものです.