[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

Re: [xsl] Here's how to create a function that has context, without passing it context


Subject: Re: [xsl] Here's how to create a function that has context, without passing it context
From: Dimitre Novatchev <dnovatchev@xxxxxxxxx>
Date: Fri, 16 Nov 2012 16:17:18 -0800

Even more simply, one can use a function, which has been created as a
partial application of another function, passing a subset of all
required arguments -- these form the "context".

Cheers,
Dimitre

On Fri, Nov 16, 2012 at 4:07 PM, Michael Kay <mike@xxxxxxxxxxxx> wrote:
>
>
> Your example can actually be achieved rather more simply, because
> functions have always had access to global variables. You could have done
> this using only 2.0 features:
>
> <xsl:variable name="root" select="/"/>
>
> <xsl:function name="f:author">
>   <xsl:param name="arg" as="xs:string"/>
>   <xsl:sequence select="$root//author[name=$arg]"/>
> </xsl:function>
>
> But what you're starting to discover, I think, is the fact that a
> dynamically-created function can hold data as well as algorithm. The data
> (which you call "context") usually goes by the name of a "closure":
> basically, at the time the function is created, it can "capture" the values
> of all local variables that are in scope at the time it was created, and use
> these values when it is subsequently invoked. The joys of functional
> programming!
>
> Michael Kay
> Saxonica
>
>
>
> On 16/11/2012 23:28, Costello, Roger L. wrote:
>>
>> Hi Folks,
>>
>> Suppose that you would like to create a function that, given the title of
>> a book, it returns the author.
>>
>> For example, this function call:
>>
>>      author('The Society of Mind')
>>
>> returns this author:
>>
>>       Marvin Minsky
>>
>> Notice that the function, author(), was just provided a string and no
>> context.
>>
>> How can the function obtain the author without being given any context?
>> Recall that functions supposedly have no context and you must give it
>> (through parameters) all the context it needs.
>>
>> In this message I show how to create functions that have context, but you
>> don't have to give it the context.
>>
>> This technique is so cool.
>>
>> Here is the XML document that the function will operate on:
>>
>> <Books>
>>      <Book>
>>            <Title>Six Great Ideas</Title>
>>            <Author>Mortimer J. Adler</Author>
>>      </Book>
>>      <Book>
>>            <Title>The Society of Mind</Title>
>>            <Author>Marvin Minsky</Author>
>>      </Book>
>> </Books>
>>
>> I create a variable, author, that is defined to be an XPath 3.0 anonymous
>> function:
>>
>> <xsl:variable name="author" select="... define author as an anonymous
>> function ... " />
>>
>> Then I invoke the "author function" with a string representing the title
>> of a book:
>>
>> <xsl:value-of select="$author('The Society of Mind')" />
>>
>> Here is the output:
>>
>>         Marvin Minsky
>>
>> This is the key to the technique:
>>
>>        Create a variable that is defined to be a function that returns a
>> function.
>>
>> Wow!
>>
>> We need to step through this very carefully.
>>
>> I create a variable, root, to which I pass the root element of the XML
>> document (Books):
>>
>>      <xsl:variable name="root" select="function(
>>
>> $root_ as element(Books)
>>
>> )
>>
>>
>> The function returns a function:
>>
>>      <xsl:variable name="root" select="function(
>>
>> $root_ as element(Books)
>>
>> )
>>
>> as function(xs:string) as item()
>>
>>
>> The function that is returned takes an argument that is a string
>> representing the title of a book and it returns the author of the book:
>>
>>      <xsl:variable name="root" select="function(
>>
>> $root_ as element(Books)
>>
>> )
>>
>> as function(xs:string) as item()
>>                                          {function($title as xs:string)
>> as item() {$root_/Book[Title eq $title]/Author}}" />
>>
>>
>> Remember the author variable? It gets the returned function:
>>
>>      <xsl:variable name="author" select="$root(/Books)" />
>>
>>
>> Okay, let's put it all together:
>> --------------------------------------------------------
>> <?xml version="1.0" encoding="UTF-8"?>
>> <xsl:stylesheet  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>>
>> xmlns:xs="http://www.w3.org/2001/XMLSchema"
>>                                 version="3.0">
>>           <xsl:output method="text"/>
>>           <xsl:variable name="root" select="function(
>>
>> $root_ as element(Books)
>>
>> )
>>
>> as function(xs:string) as item()
>>                                          {function($title as xs:string)
>> as item() {$root_/Book[Title eq $title]/Author}}" />
>>
>>      <xsl:variable name="author" select="$root(/Books)" />
>>           <xsl:template match="Books">
>>          <xsl:value-of select="$author('The Society of Mind')" />
>>      </xsl:template>
>>      </xsl:stylesheet>
>> --------------------------------------------------------
>>
>> Pretty cool, aye?
>>
>> /Roger
>



--
Cheers,
Dimitre Novatchev
---------------------------------------
Truly great madness cannot be achieved without significant intelligence.
---------------------------------------
To invent, you need a good imagination and a pile of junk
-------------------------------------
Never fight an inanimate object
-------------------------------------
To avoid situations in which you might make mistakes may be the
biggest mistake of all
------------------------------------
Quality means doing it right when no one is looking.
-------------------------------------
You've achieved success in your field when you don't know whether what
you're doing is work or play
-------------------------------------
Facts do not cease to exist because they are ignored.
-------------------------------------
Typing monkeys will write all Shakespeare's works in 200yrs.Will they write
all patents, too? :)
-------------------------------------
I finally figured out the only reason to be alive is to enjoy it.


Current Thread
Keywords