[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

RE: managing side-effects in XSLT

Subject: RE: managing side-effects in XSLT
From: "Michael Kay" <michael.h.kay@xxxxxxxxxxxx>
Date: Wed, 11 Dec 2002 10:04:00 -0000
xslt monads
> Dimitre's warning about the sequential occurrence of code in 
> XSLT templates not implying sequential execution of 
> side-effects (if any) is still spinning in my mind. I am 
> doing quite a bit of interaction with the real world in my 
> XSLT work and one of those is JDBC access. I am assuming XSLT 
> v2.0 and XPath v2.0 as implemented in Saxon 7.
> 
> Here is some use cases and I simplify the JDBC API a lot to 
> avoid cluttering the point. I will use the following 
> namespace prefixes:
> 
> DriverManager
> Connection
> PreparedStatement
> ResultSet
> 
> and now here is in imperative java code what needs to happen:
> 
> void DriverManager.registerDriver('my.Driver');
> Connection conn = DriverManager.getConnection('jdbc:my:address');
> PreparedStatement stmt =
>     conn.prepareStatement('SELECT * FROM ANSWERS WHERE 
> QUESTION=?'); void stmt.setString(1,'HOWSITGOING') // returns 
> value that set before ResultSet rset = stmt.executeQuery();
> 
> This is a nice overview of the cases:
> 
> - static functions returning void
> - static functions returning an object
> - method functions returning an object
> - method functions returning irrelevant stuff
> 
> As I noted earlier, to make sure that thing happen in this 
> order, I want to define variables for most of these steps and 
> link them together. For the very little that I comprehend of 
> the very little that I had taken the time to read about 
> monads, this notion of a variable representing an action 
> (once it is being evaluated) is somewhat related to monads.

Basically, there's no mechanism in standard XSLT to ensure that things
happen in a particular order, or to declare that extension functions
have side-effects. In Saxon, I provide the saxon:assignable attribute
for this purpose: if you set this in an xsl:variable, the variable will
be evaluated at the point it is declared.

The other technique that's available is to pretend that you are using
the result of the function. For example, write:

<xsl:variable name="stmt"
              select="conn:prepareStatement($conn, '....')"/>
<xsl:variable name="stmt1"
              select="stmt:setString($stmt, 1, 'HOWSITGOING')"/>
<xsl:variable name="result"
              select="($stmt1, stmt:executeQuery())"/>

The fact that $stmt1 is referenced in the third variable declaration
forces the system to evaluate the variable. The actual value is void,
which maps to an empty sequence, and therefore doesn't actually affect
the value of $result. 

This isn't completely optimizer-proof, of course, because the processor
might examine the Java signature of stmt:setString, decide that the
result is void, and that therefore it doesn't need to be evaluated. At
this stage, I think your only defence is to write a Java wrapper method
that declares the result to be (say) a List, but that actually returns
an empty list. It would take a very smart optimizer to see through that
little ruse.

> 
> and here is how I can imagine practically doing it:
> 
>       if(empty($drivers-registered))
>         then DriverManager.getConnection(...)
>         else false()
> 
> this is because Saxon returns an empty sequence when a 
> function returns void. But this looks silly, so at least I 
> could define a function aliasing empty as "ensured"
> 
>       if(ensured($drivers-registered))
>         then DriverManager.getConnection(...)
>         else false()

If you don't like writing if(empty()) you could just write if(not()).

And I would suggest writing "else ()" rather than "else false()" if you
don't care what the result is: it gives the expression a cleaner static
type.
> 
> but what's ugly here is that I need this "else" part, which 
> really doesn't make sense, instead of "else" I'd need to fail.

XPath 2.0 defines an error() method to cause a failure. This isn't yet
implemented in Saxon.
> 
> Another way of doing it would be to construct a sequence and 
> then pick the last value. This is sort of reminescent of the 
> LISP PROG form:
> 
>       last($drivers-registered, DriverManager.getConnection(...))
> 
> but there is no last function for sequences standard in 
> XPath,

Just use $sequence[last()]

> 
> Wouldn't it be nice if something like that was part of 
> XSLT/XPath? 

Unfortunately the WG got its fingers badly burnt trying to specify in
detail how extension functions should behave in the XSLT 1.1 working
draft. The instinct is now to steer well clear of the area and leave it
all to implementors.

Michael Kay
Software AG
home: Michael.H.Kay@xxxxxxxxxxxx
work: Michael.Kay@xxxxxxxxxxxxxx 


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


Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.