Menu

Idempotent extension functions

Help
2011-07-18
2012-10-08
  • Paul Duffin

    Paul Duffin - 2011-07-18

    I could not find any examples of implementing an
    ExtensionFunctionDefinition/Call in the provided samples which could have been
    useful but in the end it was quite easy to get something working. However, I
    think I may be missing something.

    I have a function which depends on some externally provided context
    information (passed in as a parameter), a set of supported features (which are
    just strings) but if it is called with the same set of strings it will always
    return the same value, true if they are all supported false otherwise. I have
    created my extensions of ExtensionFunctionDefinition and ExtensionFunctionCall
    and in the former I have said that it has no side effects and does not depend
    on the focus. I then have an example stylesheet that uses that function and
    calls it in a number of places passing in the same reference to the variable
    that provides the context as well as the same set of feature strings as
    literals. I expected the function call to be optimized automatically so that
    it was only called once (which ever use was processed first) and from then on
    all other usages would simply return the same value.

    However, when I tried it and debugged my code I found that the function was
    being called each time it was processed. is that expected, i.e. a limitation
    of the existing product, or is it something that I am doing wrong, or a bug.

    BTW. I tried to add another topic (which was quite long) and was told that it
    was caught in the SPAM NET. Does that mean it is lost forever or can someone
    free it somehow? I tried looking for help online but could not find anything
    about a SPAM NET on the forum topics.

     
  • Paul Duffin

    Paul Duffin - 2011-07-18

    Implementation should not be difficult.

    First, the style sheet compiler would need to identify those function call
    instances that are idempotent and the same, i.e. have the same definition,
    which is marked as idempotent (assuming existing focus and side effect options
    are not enough), and have the same set of literal parameters.

    Second, for each set of function calls it would need to allocate a slot in an
    array and replace the function calls with a special call that first checks the
    slot (in the Transformer) to see if the value has been set, if it has then
    return it, otherwise call the function and store the returned value in the
    slot (in the Transformer).

    Third, each Transformer would need to allocate an array for all the slots
    needed by its creating Templates.

     
  • Michael Kay

    Michael Kay - 2011-07-18

    Saxon doesn't implement functions as memo functions by default because it
    doesn't have the information needed to get the space/time trade-off right. In
    many cases keeping the results of previous function calls would just be a
    waste of memory. You can cause your function to behave as a memo function by
    calling it from within an XSLT wrapper function defined using <xsl:function saxon:memo-function="yes">. (If you do this, all results from the function are
    saved in memory; there's no LRU cache.)

    I'm afraid I don't know what happens to messages that SourceForge identifies
    as spam. On the whole the site seems to do quite a good job.

    The documentation for integrated extension functions will improve in the next
    release.

     
  • Paul Duffin

    Paul Duffin - 2011-07-19

    Ah, ok I did not realise that about the xsl:function. Could you not do the
    same thing for extension functions, i.e. add a "boolean memoize()" method to
    ExtensionFunctionDefinition, returns false by default but if you return true
    it behaves like an xsl:function with saxon:memo-function="yes".

     
  • Michael Kay

    Michael Kay - 2011-07-19

    Sure, it could be done in theory. But I'm not convinced it's worth the effort.

     
  • Paul Duffin

    Paul Duffin - 2011-07-19

    Got a bit side tracked, you answered my question, Saxon does not currently
    support this so I wasn't doing anything wrong. Thanks.