Request for dynamically scoped variables in XSLT

Dear XSLT users and editors,

I want to push the idea of dynamically scoped variables in an
upcoming revision of XSLT. This message is cross-mailed to
xsl-editors and xsl-list. We have at least one motion and one
second on the xsl-list and so I would like to ask the
"bystanders" to send a short note if they are in favor and
may be a slightly longer note if they are against.

The use case was best formulated by Terje Norderhaug who wrote:

USE CASE

 
> Being able to simplify the stylesheet by removing repeated parameter
> passing is reason enough for me. However, I have also missed variables
> with dynamic scope when extending predefined stylesheets.
> 
> Dynamic scoped variables may reduce the redundancy between imported
> and importing stylesheets, with associated benefits. It makes
> imported/importing stylesheets less dependent on each other by
> allowing passing of values between templates in a stylesheet without
> demands on the templates in the other stylesheet.
> 
> Say you have a stylesheet "book.xsl" containing templates to process
> the various element types in a book (e.g. book, chapter, paragraph,
> ...) where each template applies templates recursively, like this:
> 
> <xsl:template match="chapter">
>   <fo:block>
>     <xsl:apply-templates/>
>   </fo:block>
> </xsl:template>
> 
> Consider the case that you need to make a stylesheet that imports a
> third party "book.xsl" then overrides its templates for 'book' and
> 'paragraph' elements with custom processing but with a minimum of
> duplication. For some reason, you would like to pass a parameter from
> the 'book' template to the 'paragraph' template.
> 
> Unfortunately, today this requires that you duplicate and modify the
> 'chapter' template (and possibly others) from the "book.xsl"
> stylesheet to pass along the parameter. You end up with a stylesheet
> that contains most or all of the imported stylesheet.
> 
> With support for dynamic scope, the 'book' template would be able to
> bind variables that are visible for the 'paragraph' template without
> requiring modifications of other templates in "book.xsl".



The submitter(s) of this request understand that dynamic scope
in variables may be a controversial issue. There is some concern
about the purity of a functional language with dynamic scope
vis-a-vis functional arguments (RISKS), and there may be the issue
of feature bloat that need to be implemented (COSTS). It will
ultimately come down to a collective value judgement by majority
vote if the USE outweighs RISKS + COSTS.

Obviously, the submitter(s) believe that the USE is significant.
It can be expected that out of broad acceptance of XSLT there
will emerge a growing global library of XSLT templates.
Future style sheet design will increasingly involve importing
and customizing templates from other sources. The above use
case describes how such template reuse with minimal redundancy
can be significantly facilitated by a dynamic scoping mechanism
built-into XSLT.

The submitter(s) understand that it is possible to emulate
dynamically scoped variables by a node-set structure passed
down the call-chain as an explicit parameter as an "environment"
of name-value bindings. However, this emulation can only work
if all template authors will use the same convention as a
standard. If not, templates need again be cloned and modified
in order to be reused in the manner described in the use case.
This suggests that a dynamic scoping for variables is an
essential feature of the XSLT language if the above use case
is to be satisfied.

As for the RISKS the submitter(s) acknowledge that it is
understood since at least the late 1970s that dynamic scoping
is an issue with functional argument passing. However, it is
not an unsolved issue. The discovery of the issue has lead, not
to the abandoning of dynamic scoping, but to the definition of
the LISP concepts of FUNARG and later CLOSURE [1], and FLUID
bindings in CommonLISP. In later functional programming languages,
such as Scheme and Haskell, dynamic scoping was initially omitted.
However, there is some good evidence in the literature that in
both Scheme and Haskell, the practical use of dynamic scoping
to meet software engineering needs is well recognized and has
caused constructs that effect (optional) dynamic scoping to
be added in Scheme [2] and at least one significant Haskell
contribution of a similar feature, called implicit parameters
[3]. This suggests that for a class of problems analogous to
the above use case, an optional dynamic scoping is an essential
construct.

As a provisional side argument, I would submit that it is
at least not obvious where in XSLT functional arguments would
occur as a problem, since XSLT has no lamda form that could
be passed as arguments or returned as values, and template
names or modes cannot be constructed. So, this would suggest
that the RISKS of some dynamic socping functionality in XSLT
is of a more theoretical nature and may not have practical
relevance for XSLT.

As for the COSTS, implementation of dynamically scoped (fluid)
variables seems possible without affecting most parts of current
XSLT implementations. The srategy of shallow binding would
accomodate current XSLT lexical scoping and has a well known
extension into dynamic scoping [1].

The suggestion is to declare dynamic scope wherever a variable
is to participate in the dynamic scope. We would propose a
new construct, analogous to the implicit parameter, called
<param scope='implicit' .../>.  Such parameters could occur
wherever <param .../> can occur and new bindings are created
using <with-param .../> elements just as with normal
parameters.

So, a dynamically scoped parameter variable may be declared as:

<xsl:template match='colored-book'>
   <xsl:param scope='implicit' name="text-color" select="'black'"/>
   <xsl:apply-templates/>
<xsl:template/>

There continues to be no assignment statement in XSLT but
bindings to implicit parameters would be overlayed just as
it happens with explicit parameters:

<xsl:template match='red-text'>
   <xsl:param scope='implicit' name="text-color"/>
   <xsl:apply-templates>
     <xsl:with-param name="text-color" select="'red'"/>
   </xsl:apply-templates>
<xsl:template/>

As opposed to conventional explicit parameters, the parameter
bindings would be "passed through" other templates (e.g.,
chapter) that have no notion of text color in order to be
available further down the call-chain to templates that
do care about this feature:

<xsl:template match='paragraph'>
   <xsl:variable name="text-color" select="'black'" scope="dynamic"/>
   <html:p color="{$text-color}">
     <xsl:apply-templates/>
   </html:p>
</xsl:template>

only if the parameters is declared in the current lexical scope
and only if the attribute scope="implicit" is set, would the
parameter name share in the dynamic scope. An undeclared (free)
parameter would still be an error and a parameter not declared
as scope='dynamic' would follow conventional lexical scoping
semantics.

In the case of implicit parameters, the default select term is
only evaluated and its value only bound to the parameter if there
is no such binding found in the dynamic scope.

Had the variable been declared as a parameter or as a
normal variable, it would have shadowed any variable of the
same name in an outer lexical scope as well as a dynamic scope.
Thus:

<xsl:template match='green-section'>
   <xsl:param name="text-color" select="'green'"/>
   <xsl:apply-templates/>
</xsl:template>

would still behave as expected from XSLT 1.0.

In case an implicit parameter is overshadowed by an explicit
parameter or a conventional XSLT 'variable', this does not
affect the binding in the dynamic scope! The above 'green-
section' template would not create a new binding to text
color in the dynamic scope, because text-color in this
lexical scope of green-section is not declared as participating
in the dynamic scope. This keeps conventional and implicit
parameters from accidential interferrence.

With this proposal, current XSLT style sheets would continue to
work without being affected by the new dynamic scoping feature.
Yet the dynamic scoping would be available for all style sheets
evaluated with a new XSLT engine. No rewriting of existing
stylesheet and no cloning and modifying of parts of such
existing style sheets is necessary to make use of dynamic scope.


Thank you for your consideration.

sincerely,
-Gunther Schadow



REFERENCES (apart from the obvious)

[1] John Allen. Anatomy of Lisp. 1978
[2] MIT Scheme Reference 2.3: Fluid Binding
[3] Jeffrey R. Lewis, et al. Implicit Parameters: Dynamic Scoping
     with Static Types [http://citeseer.nj.nec.com/lewis00implicit.html]

-- 
Gunther Schadow, M.D., Ph.D.                    gschadow@regenstrief.org
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

Received on Wednesday, 2 January 2002 05:48:57 UTC