[xsl] managing side-effects in XSLT

Subject: [xsl] managing side-effects in XSLT
From: Gunther Schadow <gunther@xxxxxxxxxxxxxxxxxxxxxx>
Date: Tue, 10 Dec 2002 15:43:58 -0500
Hi,

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.

I welcome other suggestions, Dimitre mentioned continuation
passing, and it would be nice to see an example of that.

So, I would go

<xsl:variable name="drivers-registered"
   select="DriverManager:registerDriver('my.Driver')"/>

and now I would like to have a nice form that allows me to say that
first I need to have the drivers-registered and then I need to
get the connection.

<xsl:variable name="connection"
   select="..."/>

here are possible forms to put into the select:

ensure(drivers-registered) DriverManager.getConnection(...)

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()

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.

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, also,
this would not even ensure that the $drivers-registered are ever
evaluated because they are never asked for. The trick here is,
as I understand it, to make a form that would be guarranteed
executed in the order given.

So, I could just as well do this:

prog($drivers-registered, DriverManager.getConnection(...))

which, again, like LISP, would evaluate each argument and return the
value of the last.

Wouldn't it be nice if something like that was part of XSLT/XPath?
It seems that this needs to be a primitive function, because
nothing really guarantees this behavior in the general case.

What's the best approach?

thanks,
-Gunther

--
Gunther Schadow, M.D., Ph.D.                    gschadow@xxxxxxxxxxxxxxx
Medical Information Scientist      Regenstrief Institute for Health Care
Adjunct Assistant Professor        Indiana University School of Medicine
tel:1(317)630-7960                         http://aurora.regenstrief.org



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


Current Thread