Skip to content

Reducing proliferation of function namespaces #21

@michaelhkay

Description

@michaelhkay

As the number of function libraries increases, the number of namespace declarations required proliferates. There are several practical consequences: the code becomes more cluttered, and it also becomes slower, because namespace declarations have to be maintained at run-time, they aren't just used for compile time disambiguation. Even when exclude-result-prefixes="#all" is used in XSLT to prevent the namespaces finding their way into the result tree, there are other operations where a large static context becomes a nuisance. For example, when we compile code to SEF files, a significant proportion of the size of the compiled file is taken up with namespace information, much of which is never used. The more namespaces there are, the more likely it becomes that two functions have different namespace contexts, and when functions are inlined, the different namespace contexts need to be maintained in the optimized code.

Many languages have some kind of mechanism to allow functions to have a "full name" and a "short name" of some kind, with a reasonably flexible mechanism to allow the short name to be expanded statically to the full name. It would be good to do this without the necessity to proliferate namespace declarations that have to be maintained at run-time.

An idea for doing this, using XSLT syntax, is to allow something like this:

<xsl:function-library>
    <xsl:import-functions namespace="http://www.w3.org/2005/xpath-functions">
       <xsl:alias-function name="put#1" as="update-put"/>
    </xsl:import-functions>
    <xsl:import-functions namespace="http://www.w3.org/2005/xpath-functions/map">
       <xsl:alias-function name="put" as="map-put"/>
    </xsl:import-functions>
    <xsl:import-functions namespace="http://www.w3.org/2005/xpath-functions/array">
       <xsl:alias-function name="put" as="array-put"/>
       <xsl:alias-function name="get" as="array-get"/>
    </xsl:import-functions>
</xsl:function-library>

When an unprefixed function name is referenced, the local name (and arity) is resolved using the declared function library. The basic rule is that the reference must be unambiguous: if two of the imported function namespaces overlap, making the local-name/arity combination ambiguous, then that function is not accessible by local-name/arity, unless it has been assigned an alias.

(This rule is designed so that if one of the function libraries expands over time, causing an ambiguity to arise where there was none before, then (a) there is no failure unless the affected function is actually used, and (b) if it is used, then a static error is reported; this situation never causes the wrong function to be executed.)

To keep independence between modules, it would probably make sense for a function library to be named and for the name to be scoped to a package, and for individual modules to say explicitly what library they are using with a declaration such as <xsl:use-function-library name="xxx"/> which has module scope.

The impact on XPath, I think, is that the concept of "default function namespace" would be replaced by "unqualified function name resolution algorithm", whose value is a procedure for statically resolving a local-name/arity to a fully qualified function name; different host languages could use different resolution algorithms.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions