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.
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.
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
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".
Sure, it could be done in theory. But I'm not convinced it's worth the effort.
Got a bit side tracked, you answered my question, Saxon does not currently
support this so I wasn't doing anything wrong. Thanks.