This is the mail archive of the xsl-list@mulberrytech.com mailing list .


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Functional programming in XSLT


Hi Alexey,

> I am proposing xsl:lambda for the following reasons:
>
> 1. It is simple. It costs only one extension element and one extension
> function.

I count three extension elements (although of course you've used the
'xsl' prefix for them): xsl:lambda, xsl:return and xsl:define.

> The current proposal for <exsl:function> does not conform to this
> rule. In particular, the <exsl:result> feature, with all rules
> governing its use, looks a little bit odd for me.

Yes, it is :(  The trouble is that there are certain things that
become irritatingly difficult if you don't allow exsl:result to be
used as we have it at the moment.  If you look at the first draft for
EXSLT - Functions [1] (when it wasn't called EXSLT - Functions) you'll see
the problem illustrated with the four-argument key function:

<exsl:function name="doc:key">
   <xsl:param name="key-name" />
   <xsl:param name="key-value" />
   <xsl:param name="documents" select="/.." />
   <xsl:param name="base-URI" select="document('')" />
   <xsl:choose>
      <xsl:when test="count($documents) > 1">
         <exsl:return select="doc:key($key-name, $key-value, 
                                      $documents[1], $base-URI) |
                              doc:key($key-name, $key-value,
                                      $documents[position() != 1], 
                                      $base-URI)" />
      </xsl:when>
      <xsl:otherwise>
         <xsl:variable name="doc"
                       select="document($documents, $base-URI)" />
         <xsl:variable name="nodes">
            <xsl:for-each select="$doc">
               <xsl:for-each select="key($key-name, $key-value)">
                  <node id="{generate-id()}" />
               </xsl:for-each>
            </xsl:for-each>
         </xsl:variable>
         <xsl:variable name="doc-nodes" select="$doc//node() | $doc//@*" />
         <exsl:return select="$doc-nodes[generate-id() = $nodes/node/@id]" />
      </xsl:otherwise>
   </xsl:choose>
</exsl:function>

(Of course to fit with your xsl:define/xsl:lambda syntax then you'd
have to move the exsl:return elements to be the last element - I think
at that point you would *have* to have a conditional operator in XPath
to make it work?)

It might be that really the above is such an obscure case that the
additional complexity that trying to solve it 'elegantly' isn't worth
the cost of breaking the XSLT rules. But it seems to me that the XSLT
rules prevent the instantiation of any instruction to lead to anything
other than an RTF. So any use of exsl:result or similar is ultimately
doomed. I don't know - perhaps I'm missing something that makes
saxon:return OK and exsl:result not?

> This design is consistent with the core XSLT processing model. The
> only missing feature is a conditional operator in XPath (similar to
> the ternary operation ?: in C). This feature is badly needed to
> allow node-set manipulations using the expression-based form of
> <xsl:return> (it is well understood, that template-based form
> generating RTF cannot be efficiently used to process node-sets).

David Rosenborg's travelled a long way down this path. There are some
things that you just can't do in XPaths at the moment, and which are
essential to have the kind of syntax that you have in
xsl:define/xsl:lambda. He's added variable assignment, a conditional
expression, a reduction expression and function call steps to make
writing the kind of functions in EXSLT easy, or at least possible. [2]

> Once the conditional operator is added to XPath, the combinaton of
> <xsl:lambda> and <xsl:define> features can provide, at my opinion, a
> solid foundation for the functional programming in XSLT.

I think that you probably need a little more than a conditional
expression to be added, hence the additional stuff that David R.'s
added to FXPath. But have a look at the functions in EXSLT and try to
implement them with xsl:define. I may well be wrong, particularly as
xsl:lambda offers a new kind of functionality.

Then it comes down to impatience - there won't be any changes to XPath
until version 2.0 arrives.  We can have extension elements and
attributes now that hold things that are interpreted as an extended
XPath (i.e. FXPath).

As I understand it (which is admittedly not very much) I think that
xsl:lambda might be an interesting starting point for something
similar in EXSLT - Dynamic (something that Uche suggested the other
day).  Would it be OK to add something like that in (though possibly
adapted to tie in more with exsl:function)?

Cheers,

Jeni

[1] http://www.jenitennison.com/xslt/exslt/common/exslt-common-010225.html
[2] http://www.pantor.com/fxpath

---
Jeni Tennison
http://www.jenitennison.com/



 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]