xsl-list
[Top] [All Lists]

Re: [xsl] [xslt 2.0] Difference betwen functions and templates

2007-07-19 06:36:02
I think I believed the wrong term, I meant method overloading
instead of polymorphism. I don't agree with your statement that
single polymorphism is what is offered by XSLT. I.e., polymorphism
means that the compiler automatically chooses the correct
implementation based on the type information and inheritance
hierarchy (the cat/dog/animal examples).

What you showed was a way of overriding the default template
behavior with a more specific behavior.

POLYMORPHISM
If such a thing would exist it might look something like this:

<xsl:module name="mod:cat" implements="animal">
   <xsl:function name="talk">Meow!</xsl:function>
   <xsl:function name="name">Cat</xsl:function>
</xsl:module>

<xsl:module name="mod:dog" implements="animal">
   <xsl:function name="fu:talk">Bark!</xsl:function>
   <xsl:function name="fu:name">Cat</xsl:function>
</xsl:module>

<xsl:module name="mod:animal">
   <xsl:function name="fu:talk" deferred="yes">
   <xsl:function name="fu:name" deferred="yes">
   <xsl:function name="fu:say-name">
      <xsl:sequence select="fu:talk(), ' I am a ', fu:name()" />
   <xsl:function>
</xsl:module>

<!-- suppose that a module can be called like a xpath axis, then -->
<xsl:template match="/">
   <xsl:sequence select="'mod:dog:', mod:dog::say-name()" />
   <xsl:sequence select="'mod:cat:', mod:cat::say-name()" />
</xsl:template>

<!-- output will then be -->
mod:dog: Bark! I am a dog
mod:cat: Meow! I am a cat



Here, the processor automatically knows that mod:dog and a mod:cat
are of type mod:animal. But just calling the functions of
mod:dog/cat, you automatically have access to the 'parent' functions
in the mod:animal. Of course, this example is superfluous and this
behavior won't be inside XSLT for the next couple of years at least,
if ever.

METHOD OVERLOADING
I think that method overloading (or parametric polymorphism) is
something that is available. You mention a way of overloading by
using precedence rules, where you overload the complete method.
Method overloading is only available from XSLT 2.0, and only very
basically. I.e., only arity overloading is possible, type
overloading (unfortunately, missed chance, W3C) is not.

<!-- implementation function -->
<xsl:function name="fu:outline" as="xs:string">
   <xsl:param name="input" as="xs:string" />
   <xsl:param name="size" as="xs:integer" />
   <xsl:sequence select="... $size - length($input) etc..." />
</xsl:function>

<!-- simple overloading by arity -->
<xsl:function name="fu:outline" as="xs:string">
   <xsl:param name="input" as="xs:string" />
   <xsl:sequence select="fu:outline($input, 20)" />
</xsl:function>


<!-- adding overloading by type, illegal -->
<xsl:function name="fu:outline" as="xs:string">
   <xsl:param name="input" as="xs:integer" />
   <xsl:sequence select="...right-outline-integer..." />
</xsl:function>



Overloading by arity is often nothing more than giving default
values to missing arguments. A design like named templates with
default values would perhaps have been easier.

All we can do is doing the type overloading by hand, which is not
nice and clutters your code with many unnecessary statements:

<xsl:function name="fu:outline" as="xs:string">
   <xsl:param name="input" as="xs:anyAtomicType" />
   <xsl:if test="$input cast as xs:integer">
      ... etc
   </xsl:if>
   <xsl:if test="$input cast as xs:string">.... etc
<xsl:function>



Ah well, I probably don't tell anything new here, but I just wanted
to clarify my point. Sorry for the verbosity of the post ;)


Cheers,
-- Abel Braaksma



On 7/19/07, Abel Braaksma <abel(_dot_)online(_at_)xs4all(_dot_)nl> wrote:
   6. If you want polymorphism (partially, only nr of arguments)
you
must use a function

You can use import precedence with named templates  to get single
polymorphism eg:

"Specific.xslt" :

<xsl:import href="common.xslt"/>

<xsl:template match="/">
      <xsl:call-template name="commonTemplate"/>
</xsl:template>

<xsl:template name="poly">Specfic</xsl:template>


and then "Common.xslt" :

<xsl:template name="commonTemplate">
      <xsl:call-template name="poly"/>
</xsl:template>

<xsl:template name="poly">Common</xsl:template>

The output is "Specific" because the named template "poly" in the
specific stylesheet has a higher import precedence than that in the
common stylesheet.

You can make the poly template in common pseudo-abstract by doing
something like:

<xsl:template name="poly">
  <xsl:message terminate="yes" select="'This stylesheet must be
imported by another stylesheet and cannot be run on its own...'"/>

cheers
andrew





--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--