Re: [xsl] Processing based on number - alternatives to recursion?

Subject: Re: [xsl] Processing based on number - alternatives to recursion?
From: David Carlisle <davidc@xxxxxxxxx>
Date: Tue, 4 Mar 2008 17:19:49 GMT
>  Supplying the stylesheet file name
> as a parameter to the stylesheet and calling document() on it?

 <xsl:variable name="here" select="."/>
<xsl:for-each select="(document('')//*)[position()&lt; 10]">
  <xsl:variable name="p" select="position()"/>
       code using $here and $p as needed...

note this looks short but can easily be less efficient than the
recursive template version as it implies loading the stylesheet and
parsing the entire thing just to get a bunch of nodes to iterate over.
(For various reasons the system will probably need to reparse the
stylesheet as an input doc, not use the in-memory tree resulting from
the initial parse of the stylesheet). If on the other hand you know your
input doc will be big enough, you already have those nodes to hand so 
<xsl:for-each select="(//*)[position()&lt; 10]">
is probably fairly cheap.


> Lots of stack space is what I thought. Does tail recursion mean there
> is nothing left to process in the current round when the template
> recursively invokes itself?

more or less. googling for that phrase will yield arbitrary amounts of
detail:-) Basically there are theorems that tell you that certain
classes of problem can be written in tail recursive style (and certain
classes can not) and that those that are tail recursive can essentially
be implemented as a loop. this means that compilers can "compete" in how
good a job they can do at optimising tail recursive calls by rewriting
functions in tail recursive style even if the end user has not coded it
that way explictly. The factorial function is (always;) the standard
example.

5! is 5*4*3*2*1

if you code it as

fac(n) = n * fac(n-1) if n > 1 else 1

then that is not tail recursive and the  fac(5) ends up with a stack of
all 5 function calls being partially evaluated until you finally get down
to fac(1) and you pop the stack (or run out of stack:-)

if instead you do

fac(n)= fac(n,1)
fac(n,r)=fac(n-1,n*r) if n>1 else r

then the intermediate results are built up in the parameter list and so
you don't need to preserve the function call stack you can just
reuse the same space at each iteration (in otherwords it's essentially a
loop).



> Does the call have to be placed at the end of the recursive template
> in order for this to happen?

yes for some definition of "end" for example the recursive call inside a
conditional block ought to count as "end" (you normally need that to
terminate recursion). so in xslt the recursive call might not actually be
the last line, there may be various /xsl:when/xsl:choose etc.

David

________________________________________________________________________
The Numerical Algorithms Group Ltd is a company registered in England
and Wales with company number 1249803. The registered office is:
Wilkinson House, Jordan Hill Road, Oxford OX2 8DR, United Kingdom.

This e-mail has been scanned for all viruses by Star. The service is
powered by MessageLabs. 
________________________________________________________________________

Current Thread