<?xml-model href="http://docbook.org/xml/5.1/rng/docbook.rng" schematypens="http://relaxng.org/ns/structure/1.0"?><?xml-model href="http://docbook.org/xml/5.1/sch/docbook.sch" type="application/xml" schematypens="http://purl.oclc.org/dsdl/schematron"?>
<article xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:lang="en_GB" version="5.1">
    <info>
        <title>Task Abstraction for XPath Derived Languages</title>
        <date>2019-01-31</date>
        <author>
            <personname>
                <honorific>Dr</honorific>
                <firstname>Debbie</firstname>
                <surname>Lockett</surname>
            </personname>
            <affiliation>
                <orgname>Saxonica</orgname>
                <address>
                    <city>Reading</city>
                    <country>United Kingdom</country>
                </address>
            </affiliation>
            <email>debbie@saxonica.com</email>
        </author>
        <author>
            <personname>
                <firstname>Adam</firstname>
                <surname>Retter</surname>
            </personname>
            <affiliation>
                <orgname>Evolved Binary</orgname>
                <address>
                    <city>London</city>
                    <country>United Kingdom</country>
                </address>
            </affiliation>
            <email>adam@evolvedbinary.com</email>
        </author>
        <abstract>
            <para>
                <acronym xml:id="acr_XPDL" linkend="bacr_XPDL">XPDL</acronym>s (<phrase xml:id="bacr_XPDL" linkend="acr_XPDL">XPath Derived Language</phrase>s)
                such as XQuery and XSLT have been pushed beyond the envisaged scope of their designers. Perversions
                such as processing Binary Streams, File System Navigation, and Asynchronous Browser <acronym>DOM</acronym>
                Mutation have all been witnessed.</para>
            <para>Many of these novel applications of XPDLs intentionally incorporate non-sequential and/or concurrent
                evaluation and embrace side effects to achieve their purpose.</para>
            
            <para>To arrive at a solution for safely managing side effects and concurrent execution, this paper first surveys both the available XPDL vendor extensions and
                approaches offered in non-XPDLs, and then describes <emphasis>EXPath Tasks</emphasis>, a novel solution derived for the safe evaluation
                of side effects in XPDLs which respects both sequential and concurrent execution.</para>
        </abstract>
        
<!-- TODO strengthen the abstract when we have the body content complete -->

    </info>
    <sect1>
        <title>Introduction</title>
        <para>XPath 1.0 was originally designed to <quote>provide a common syntax and semantics for functionality shared between XSL Transformations and XPointer</quote> <biblioref linkend="bib_xpath10"/>,
            and XPath 2.0 pushed the abstraction further by declaring <quote>XPath is designed to be embedded in a host language such as XSL Transformations ... or XQuery</quote> <biblioref linkend="bib_xpath20"/>.
            For XML processing, XPath has enjoyed an arguably unparalleled level of language adoption through reuse, forming the basis of XPointer, XSLT, XQuery, XForms, XProc, Schematron, JSONiq, and others.
            XPath has also had a wide influence outside of XML, with concepts and syntax being reused in other languages like <acronym xml:id="acr_aql" linkend="bacr_aql">AQL</acronym> (<phrase xml:id="bacr_aql" linkend="acr_aql">Arrango Query Language</phrase>),
            Cypher, JSONPath, and <acronym xml:id="acr_odata" linkend="bacr_odata">OData</acronym> (<phrase xml:id="bacr_odata" linkend="acr_odata">Open Data Protocol</phrase>) amongst others.</para>
        
        <para>As functional languages,
            XPDLs such as XQuery were designed to avoid strict or
            ordered evaluation <biblioref linkend="bib_robie16"/>, thus leaving them open to optimisations which may
            exploit concurrency or parallelism. XPDLs are thus good candidates for event
            driven and task based concurrent and/or parallel processing. Since 2001, when the first non-embedded multi-core processor the IBM Power 4 <biblioref linkend="bib_ibm_power4"/> was introduced, CPU manufacturers have followed the trend of offering
            improved performance through greater numbers of parallel hardware threads as opposed to increased clock
            speeds. Unfortunately, exploiting the performance of additional hardware threads puts an additional burden
            on developers by requiring the use of low-level complex concurrent programming techniques <biblioref linkend="bib_perrone09"/>. Such low-level concurrent programming is often error-prone <biblioref linkend="bib_fonseca_11"/>, so it is desirable to employ higher level abstractions such as event driven
            architectures <biblioref linkend="bib_loring17"/>, or task based computation with Futures <biblioref linkend="bib_baker77"/> and Promises <biblioref linkend="bib_friedman76"/>. This paper advances the use of XPDLs in this context.</para>
        
        <para>Indeed, the formal semantics for XPath state that <quote>[XPath/XQuery] is a functional language</quote> <biblioref linkend="bib_xpath20_fs"/>.
            From this we can infer that strict XPDLs must therefore also be functional languages; this inference is strengthened by XQuery and XSLT which are both functional languages.
            By placing restrictions on expression formulation, composition, and evaluation, functional programming languages can enable advantageous classes of verification and optimisation when compared to imperative languages.
        </para>
        
        <para>One such restriction enforced by functional languages is the elimination of <emphasis>side effects</emphasis>. A side effect is defined as a function or expression modifying some state which is external to its local environment,
            this includes:
            <orderedlist>
                <listitem>
                    <para>Modifying either: a global variable, static local variable, or variable passed by reference.</para>
                </listitem>
                <listitem>
                    <para>Performing I/O.</para>
                </listitem>
                <listitem>
                    <para>Calling other side effect functions.</para>
                </listitem>
            </orderedlist>

            XPath and the XPDLs as defined by the W3C specifications address these concerns and prevent side effects by enforcing that:
            <orderedlist>
                <listitem>
                    <para>Global variables and static local variables are immutable, and that variables are always passed by value and not reference.</para>
                </listitem>
                <listitem>
                    <para>I/O is frozen before evaluation, only documents known to the immutable static context may be read, whilst the only output facility is the <acronym linkend="bacr_XDM">XDM</acronym> result of the program.</para>
                </listitem>
                <listitem>
                    <para>There are no side-effecting functions<footnote>
                        <para>XPath 3.0 defines only one absolute non-deterministic function
                                    <function>fn:error</function>, and several other functions
                                    (<function>fn:analyze-string</function>, <function>fn:parse-xml</function>,
                                    <function>fn:parse-xml-fragment</function>, <function>fn:json-to-xml</function>, and
                                    <function>fn:transform</function>) which could be non-deterministic depending on
                                implementation choices. We devalue the significance of <function>fn:error</function>'s
                                side effect by tendering that, it could equally have been specified as a language
                                expression for raising exceptions as opposed to a function.</para>
                        </footnote>.</para>
                </listitem>
            </orderedlist>
            In reality though many XPDL implementations offer
            additional vendor-specific <quote>
                <emphasis>extensions</emphasis>
            </quote> which compromise functional integrity to permit side effects so that I/O can be more easily achieved by the developer.
            Of concern for this paper is the ability to utilize XPDLs for complex I/O requiring side effects without compromising functional integrity or correctness of the application.
        </para>
        
        <para>The key contributions of this paper are:
            <orderedlist>
                <listitem>
                    <para>A survey of <acronym linkend="bacr_XPDL">XPDL</acronym> vendor implementations, detailing both
                        how they manage side effects and any proprietary extensions they offer for concurrent execution.
                        See <xref linkend="sect_survey-xpdl-vendors"/>.</para>
                </listitem>
                <listitem>
                    <para>A survey of currently popular mechanisms for concurrent programming in non-XPDLs, their ability to manage side effects, and their potential for XPDLs. See <xref linkend="sect_survey-non-xpdls"/>
                    </para>
                </listitem>
                <listitem>
                    <para>EXPath Tasks, a module of XPath functions defined for managing computational side effects and
                        enabling concurrent and asynchronous programming. To demonstrate the applicability of EXPath
                        Tasks, we offer experimental reference implementations of this module in XQuery, XSLT, Java (for
                        use from XQuery in eXist-db), and JavaScript (for use from XSLT in Saxon-JS). See <xref linkend="sect_expath_tasks"/>.</para>
                </listitem>
            </orderedlist>
        </para>
        
        <para>We next briefly examine the original vision for XPath, XQuery, and XSLT, with particular concern for how these languages should be evaluated by processors. We then
            examine how the use of these languages has evolved over time and some of the unexpected and novel ways in which they have been used.</para>
            
        <sect2>
            <title>The vision of XPDLs</title> 
            <para>The design requirements of XPath 2.0 <biblioref linkend="bib_xpath20_req"/> mostly focused on that of exploiting the <acronym xml:id="acr_XDM" linkend="bacr_XDM">XDM</acronym>
                (<phrase xml:id="bacr_XDM" linkend="acr_XDM">XQuery and XPath Data Model</phrase>) and interoperability. As a language designed to describe the processing abstractions of various
                host languages, it did not need to state how the evaluation of such abstractions should take place, although we find that it was not without sympathy
                for implementations, as one of the stated Goals was: <quote>Enable improved processor efficiency</quote>; unfortunately, we found little explicit
                public information on how or if that goal was met.</para>
            <para>Examining the XQuery 1.0 requirements <biblioref linkend="bib_xquery10_req"/> we find a similar focus upon the <acronym linkend="bacr_XDM">XDM</acronym>, where querying different
                types of XML documents, and non-XML data sources is possible, provided that both can present their data in an <acronym linkend="bacr_XDM">XDM</acronym> form. However, the XQuery 1.0 specification makes an explicit
                statement about evaluation: <quote>an implementation is free to use any strategy or algorithm whose result conforms to the specifications in this document</quote>,
                thus giving implementations a great deal of freedom in how the query should be evaluated.</para>
            <para>One of the requirements of XSLT 2.0 is labelled <quote>2.11 Could Improve Efficiency of Transformations on Large Documents</quote> <biblioref linkend="bib_xslt20_req"/>. It describes both the
                situation where the tree representation of source documents may exceed memory requirements, and a desire to still be able to process such large documents. It uses non-prescriptive
                language to suggest two possible solutions: 1) a subset of the language which would not require random access to the source tree, we could likely recognise XSLT 3.0 Streaming as the implementation
                of that solution, and 2) splitting a tree into sub-trees, performing a transformation on each sub-tree, and then copying the results to the final result tree. Whilst XSLT 2.0
                does not state how an implementation should be achieved, many would likely recognise that (2) is an <emphasis>embarrassingly parallel</emphasis> problem that would likely
                benefit from a MapReduce <biblioref linkend="bib_dean04"/> like approach.</para>
            <para>An academic example of exploiting the implicit parallelisation opportunites of XPDLs is PAXQuery, which compiles a subset of XQuery down into MapReduce jobs which
                can execute in a highly-parallel manner over a cluster of Hadoop nodes <biblioref linkend="bib_camacho-rodríguez15"/>.
                To the best of our knowledge, Saxon is the only commercial XPDL processor which attempts implicit parallelisation. However, Michael Kay reports that
                within the XSLT processor it can be difficult to determine when implicitly parallelising operations will reduce processing time <biblioref linkend="bib_kay15"/>. 
                Saxon therefore also offers vendor extensions which allow an XSLT developer with a holistic view of both the XSLT and the data it must process,
                to explicitly annotate certain XSLT instructions as parallelisable.</para>  
        </sect2>
        
        <sect2>
            <title>Novel applications of XPDLs</title>
            <para>XPDLs have been used in many novel situations for which they were never envisaged, many of which
                utilise non-standardised extensions for I/O side effects and concurrent processing to achieve their
                goals.</para>
            <sect3>
                <title>XPDLs as Web Languages</title>
                <para>XPDLs, in particular XQuery, have been adopted with considerable success as server-side scripting
                    languages for the creation of dynamic web pages and web APIs. A web page is by definition a
                    document, and since an HTML document is representable as an XML document, XPDLs' ability to
                    build and transform such documents from constituent parts has contributed to their uptake.
                    Implementations such as BaseX, eXist-db, and MarkLogic all provide HTTP Servers which execute XQuery
                    in response to HTTP requests. Whilst a single XQuery may be executed concurrently by many thousands
                    of users in response to incoming HTTP requests, stateful information often needs to be persisted and
                    shared on the server. This could be in response to either a user logging into a secure website, at
                    which point the server must establish a session for the user and memorize the users identity; or
                    multiple web users communicating through the server, for example, updating stock inventory for a
                    shopping basket or social messaging. Regardless, such operations require the XPDL to make
                    side-effecting changes to the state of the server or related systems.</para>
                <para>XSLT's main strength as a transformation language for XML is equally applicable to constructing or
                    styling HTML web pages. Web browsers offer limited XSLT 1.0 facilities, which can be either applied
                    to XML documents which include an appropriate Processing Instruction, or invoked from JavaScript.
                    The XSLT process offered by the web browser vendors is a black-box transformation, whereby an XSLT
                    stylesheet is applied to an XML input document, which produces output. This XSLT process is
                    completely isolated and has no knowledge of the environment from which it is called; it can not read
                    or write directly to or from the web page displayed by the browser. In contrast, in recent years
                    Saxonica has provided JavaScript based processors which run directly within the web browser,
                    removing the isolation and allowing access to the web page state and events via XSLT extensions.
                    First with Saxon-CE, a ported version of the XSLT 2.0 Saxon Java processor, and then with Saxon-JS,
                    a clean implementation of XSLT 3.0 in JavaScript. The XSLT extensions designed for use with these
                    processors make use of asynchronous processing (as demanded by JavaScript) and side effects to read
                    and write the DOM model of the web page.</para>
                <para>Similar to Saxon-CE, although now unmaintained another notable example is XQiB. XQiB implements an
                    XQuery 1.0 processor in JavaScript which runs in the web browser and provides a number of XQuery
                    extension functions which cause side effects by writing directly to the HTML DOM and CSS <biblioref linkend="bib_xqib"/>.</para>
            </sect3>
            <sect3>
                <title>Binary Processing with XPDLs</title>
                <para>The generation of various binary formats using XPDLs has also been demonstrated. One such example is Philip Fennel's generation of TIFF format images, which
                    uses a Reyes pipeline written in XSLT <biblioref linkend="bib_fennel13"/>. One of Fennel's conclusions with regard to execution was that <quote>Certainly it is not fast and it is not very
                        efficient either</quote>. It is not hard to imagine that if concurrent processing was applied to each stage of the pipeline, so that stages were processed in parallel, then execution time might be significantly reduced.</para>
                <para>Two XPath function extension modules produced by the EXPath project, the Binary <biblioref linkend="bib_expath_bin10"/> and File Module <biblioref linkend="bib_expath_file10"/> specifications, allow the user to both read and write files and manipulate binary data at the byte level
                    from within XPDLs. In particular, the File Module, which provides I/O functions, states that some functions are labelled as <emphasis>non-deterministic</emphasis>; this specification lacks the detail required
                    to determine if implementations are forced to produce side effects when the functions are evaluated, or whether they are allowed to operate on a static context and only apply I/O updates after execution.
                    The authors of this paper believe that it would be beneficial to have a more formal model within that specification, possibly one which allows implementers flexibility to determine the scope of side effects.</para>
            </sect3>
            
<!-- TODO should we add some more example, e.g.
                    - FOXPath filesystem navigation - https://www.balisage.net/Proceedings/vol17/print/Rennau01/BalisageVol17-Rennau01.html
                    - Temporal Axis
                        - https://docs.marklogic.com/temporal:axes
                        - Paper "Adding Valid Time to XPath", Zhang. 2002.
                        - Other papers on temporal stuff
                    - Graphs
                        - "Querying graph databases with XPath" by Leonid Libkin, Wim Martens, Domagoj Vrgoč , 2013
                        - "XPath and Modal Logics for Finite DAGs" by Maarten Marx - In Proc. of TABLEAUX’03 , 2003
            -->
        </sect2>

<!-- TODO what about PULs? -->
        
        <sect2>
            <title>Motivation</title>
            <!-- TODO ADAM: please check my (phrase, acronym) markup!
                e.g. I neglected to mention previously that Saxon-CE DID use a PUL. Now added; but perhaps this is now
                the first time PULs are mentioned?  -->
            <para>To enable side effects in a web application running in Saxon-JS, the <acronym xml:id="acr_IXSL" linkend="bacr_IXSL">IXSL</acronym> (<phrase xml:id="bacr_IXSL" linkend="acr_IXSL">Interactive
                    XSLT</phrase>) extensions (instructions, functions and modes) are provided (as previously developed
                for Saxon-CE, with some further additions and improvements). These IXSL extensions allow rich
                interactive client-side applications to be written directly in XSLT.</para>
            <para>Saxon-CE used a <phrase linkend="acr_PUL">Pending Update List</phrase> (<acronym linkend="bacr_PUL">PUL</acronym>) to make all HTML page DOM updates (side effects) at the end
                of a transform (e.g. setting attributes on HTML page nodes using <code>ixsl:set-attribute</code>; and
                adding content to the HTML page using <code>xsl:result-document</code>.) Currently Saxon-JS does not use
                a PUL, instead these side-effecting changes are allowed to execute immediately as the instructions are
                evaluated, and it is up to the developer of a Saxon-JS application to ensure that adverse affects are
                avoided. Since inception, the intention has been to eventually provide better implicit handling. Should
                the use of PULs be reinstated, or is there an alternative solution?</para>
            <para>Meanwhile, use of asynchronous (concurrent) processing is essential for user-friendly modern web
                applications. Whenever the client-side needs to interact with the server-side, to retrieve resources, or
                make other HTTP requests, this should be done asynchronously. The application may provide a "processing,
                please wait" message to the user, but it should not just stop due to blocking.</para>
            <para>The <code>ixsl:schedule-action</code> instruction allows the developer to make use of concurrent
                threads, and in particular allows for asynchronous processing. In Saxon-JS, different attributes are
                defined to cater for specific cases where there is a known need. The <code>document</code> attribute is
                used to initiate asynchronous document fetches; the <code>http-request</code> attribute is used for
                making general asynchronous HTTP requests; and the <code>wait</code> attribute was designed to force a
                delay (e.g. to enable animation), but actually simply provides a way to start any concurrent process.
                Effectively this provides a mechanism for forking, but there is no offical joining. Are there cases that
                require a join? Are there other operations which a developer could want to make asynchronously? Rather
                than building IXSL extensions for each operation, we would prefer to realise a general mechanism for
                asynchronous processing in XPDLs and by extension XSLT. Continually updating the syntax and
                implementation of <code>ixsl:schedule-action</code>, each time a new requirement arises (e.g. how to
                allow HTTP requests to be aborted), is not ideal. In particular, the IXSL HTTP request facility was
                based on the first EXPath HTTP Client Module, recent work on a second version <biblioref linkend="bib_retter18"/> of that module could be advantageous for us. However, by itself it neither
                prescribes synchronous or asynchronous operation. So, how could we implement in a manner which is both
                asynchronous and more abstract, requiring few, if any, changes to add additional modules in
                future?</para>
        </sect2>
        
        <sect2 xml:id="sect_our-requirements">
            <title>Our Requirements</title>
            <para>Applications that cannot perform I/O and/or launch parallel processes are unusual. Both I/O and
                starting parallel processes are side effects, and as discussed, explicitly forbidden within XPDLs,
                although often permitted by vendors at the cost of imperative interpretation and lost optimisation
                opportunities.</para>
            
            <para>We aim to break the trade-off between program correctness and deoptimisation in XPDLs. We require a
                mechanism that satisfies the following requirements: <itemizedlist>
                    <listitem>
                        <para>A mechanism for formulating processes which manage side effects, yet at the same time remains within
                            the pure functional approach dictated by the XPDL formal semantics.</para>
                    </listitem>
                    <listitem>
                        <para>Permits some form of parallel or concurrent operation, that is implementable on
                            systems that offer either preemptive or cooperative multitasking.</para>
                    </listitem>
                    <listitem>
                        <para>Allows parallelisation to be explicitly described, but that should not limit the
                            opportunities for implicit parallelisation.</para>
                    </listitem>
                    <listitem>
                        <para>Any parallel operation explicitly initiated by the developer, should be
                            cancellable.</para>
                    </listitem>
                    <listitem>
                        <para>Composability: it should be possible to explicitly compose many side-effecting
                            processes together in a manner that is both pure and ensures correct order of
                            execution.</para>
                    </listitem>
                </itemizedlist>
            </para>

            <para>Regardless of the mechanism, we require that it should be as widely applicable as possible, therefore it should be either:
                <itemizedlist>
                    <listitem>
                        <para>Formulated strictly in terms of XPath constructs so that it be reused by any XPDL.</para>
                        <para>Ideally, rather than developing a superset of the XPath grammar, a module of XPath extension functions
                            should be defined. The module approach has been successfully demonstrated by the EXPath project, and would likely lower the barrier to adoption.</para>
                    </listitem>
                    <listitem>
                        <para>A clearly defined abstract processing model which can have multiple syntactical expressions.</para>
                        <para>Such a model could for example provide one function-based syntax for XQuery, and another instruction-based syntax for XSLT.</para>
                    </listitem>
                </itemizedlist>
            </para>

<!-- TODO any more? -->
                
        </sect2>
    </sect1>
    <sect1 xml:id="sect_survey-xpdl-vendors">
        <title>Current Approaches by Implementers</title>
        <para>This survey provides a brief review of the offerings of the most visible XQuery and XSLT implementations
            for both concurrent and/or asynchronous execution, and how they manage side effects.</para>
        
<!-- TODO is it worth mentioning XProc and side effects above? See - https://www.w3.org/TR/xproc/#parallelism -->
        
        <sect2>
            <title>BaseX</title>
            
            <para>For concurrent processing from within XQuery, BaseX provides two mechanisms: a Jobs XQuery extension
                module <biblioref linkend="bib_basex_jobs"/>, and an XQuery extension function called
                    <function>xquery:fork-join</function>. The latter is actually an adoption of xq-promises's
                    <function>promise:fork-join</function> function, which we cover in detail in <xref linkend="sect_xq-promise"/>. The former, the Jobs Module, allows an XQuery to start another XQuery
                by calling either of two XPath functions <function>jobs:invoke</function> or
                    <function>jobs:eval</function>. Options can be supplied to both of these functions, which instead of
                executing the query immediately, schedule it for later execution. Whilst deferred scheduled queries are
                possibly executed concurrently we will not consider them further here as our focus is concurrent
                processing for the purposes of completing an immediate task. BaseX describes these functions as
                    <emphasis>asynchronous</emphasis>, and whilst technically true, unlike other asynchronous
                programming models the caller neither provides a callback function nor receives a promise, and instead
                has to either poll or wait in the main query for the result. We believe these functions could more aptly
                be described as <emphasis>non-blocking</emphasis>.</para>

            <para>Asynchronously starting another XQuery in BaseX returns an identifier which can be used to either stop
                the asynchronously executing query, retrieve its result (if it has completed), or to wait until it has
                completed. The lifetime of the asynchronously executing query is not dependent on the initiating query,
                and may continue executing after the main query has completed. In many ways this is very similar to a
                Future (see <xref linkend="sect_promises_and_futures"/>).</para>

            <para>BaseX implements XQuery Update <biblioref linkend="bib_xquery_update30_puls"/> which allows updates to
                XML nodes to be described from within XQuery via additional update statement syntax. XQuery Update makes
                use of a <acronym xml:id="acr_PUL" linkend="bacr_PUL">PUL</acronym> (<phrase xml:id="bacr_PUL" linkend="acr_PUL">Pending Update List</phrase>) which holds a set of Update Primitives. These Update
                Primitives describe changes that will be made, but have not yet been applied. These changes are not
                visible to the executing query, the PUL is output alongside the <acronym linkend="bacr_XDM">XDM</acronym> when the query completes. This is not entirely dissimilar to how Haskell eventually
                evaluates an IO monad (see <xref linkend="sect_haskell_io_monad"/>). To further facilitate additional
                common tasks required in a document database without conflicting with XQuery Update or resorting to
                side effects within an executing query, BaseX also provides many vendor specific Update Primitives in
                addition to those of XQuery Update. These include primitives for database operations to replace, rename
                and delete documents; manage users; and backup and restore databases <biblioref linkend="bib_basex_pul"/>. The use of an XQuery Update PUL avoids side effects for updates, as it only describes what will
                happen at evaluation time, leaving the actual updates to be applied at execution time. Ultimately BaseX
                applies the PUL to modify the state of its database after the query completes and the transaction is
                committed, thus making the updates visible to subsequent transactions. </para>
            
            <para>Regardless of its support for PULs, BaseX does not quite manage to entirely avoid side effects during
                the execution of some queries. BaseX offers a number of XQuery extension functions which are known to
                cause side effects, including for example, those of the EXPath HTTP and File Modules. Internally such
                side-effecting functions are annotated as <emphasis>nondeterministic</emphasis>, and will be treated
                differently by BaseX's query compiler. By skipping a range of otherwise possible query optimisations,
                BaseX ensures that the execution order of the functions within a query is as a user would expect even
                when these nondeterministic functions are present. In the presence of nondeterminism, optimisations that
                are skipped include: pre-evaluation, reordering of let clauses, variable inlining, and disposal of
                expressions that yield an empty sequence. </para>

        </sect2>
        <sect2>
            <title>eXist-db</title>
            <para>eXist-db does not present a cohesive solution for concurrent processing from within XQuery. Until
                recently, eXist-db had a non-blocking XPath extension function named
                    <function>util:eval-async</function>
                <biblioref linkend="bib_exist_eval-async"/> which could start another XQuery asynchronously. Like BaseX
                it returned an identifier for the executing query and did not accept a callback function or provide a
                promise. Unlike BaseX however, there were no additional functions to control the asynchronously
                executing query or obtain its result, rather the asynchronously executing query would run to completion
                and its result would be discarded, although it may have updated the database via side effects. This
                facility proved not to be particularly practical and has since been removed. Similarly to BaseX,
                eXist-db provides a Scheduler XQuery extension module <biblioref linkend="bib_exist_scheduler"/> for
                scheduling the future (or immediate) execution of jobs written in XQuery. Unfortunately even if an
                XQuery is scheduled for immediate execution, there is no mechanism for obtaining the result of its
                execution from the initiating XQuery.</para>
            <para>eXist-db makes no attempts to avoid side effects during processing, and instead offers many extension functions and a syntax for updating nodes that cause
                side effects by immediately modifying external state and making the modifications visible.
                eXist-db also relaxes the XPath deterministic constraint upon Available Documents, and Available Collections, allowing
                a query to both modify which documents and collections are available (a side effect), and to see changes made by concurrently
                executing queries.</para>
            <para>eXist-db is able to suffer side effects, through making several compromises:
                <itemizedlist>
                    <listitem>
                        <para>eXist-db offers the lowest transaction isolation level when executing XQuery - Read
                            Uncommitted.</para>
                        <para>eXist-db makes XQuery users somewhat aware of this, and provides XPath extension functions which enable them to lock documents and collections on demand if they require a stronger isolation level.</para>
                    </listitem>
                    <listitem>
                        <para>eXist-db executes XQuery sequentially as though it was a procedural program.</para>
                        <para>Whilst some query rewriting is employed to improve performance, eXist-db cannot exploit
                            many of the more advanced optimisations available to functional language compilers: any
                            reordering of the XQuery program's execution path could cause the program to return
                            incorrect results, due to side effects being applied in an order that the XQuery developer
                            had not intended.</para>
                        <para>Likewise, eXist-db cannot easily parallelise the execution of disjoint statements within
                            an XQuery: as shared-state modified by side effects could introduce race conditions in the
                            XQuery developer's application.</para>
                    </listitem>
                </itemizedlist>
            </para>
        </sect2>
        <sect2>
            <title>MarkLogic</title>
            <para>MarkLogic provides an XPath extension function named <function>xdmp:spawn</function>, which allows
                another XQuery to be started asynchronously from the calling query. This is done by placing it on the
                task queue of the MarkLogic task server, and this query may be executed concurrently if the task server
                has the available resources. The function is <emphasis>non-blocking</emphasis>, and for our interests
                has two modes of operation controlled by an option called <code>result</code>. When the
                    <emphasis>result</emphasis> option is set to <emphasis>false</emphasis>, the calling query has no
                reference to the queued query, and like eXist-db it can neither retrieve its result, enquire about its
                status, or abort its execution. When the <emphasis>result</emphasis> option is set to
                    <emphasis>true</emphasis>, the <function>xdmp:spawn</function> function returns what MarkLogic
                describes as a <quote>value future for the result of the spawned task</quote>. This <quote>value
                    future</quote> is quite unusual, and certainly a vendor extension with no corresponding type in
                    <acronym linkend="bacr_XDM">XDM</acronym>. Essentially, after calling
                    <function>xdmp:spawn</function> with the <emphasis>return</emphasis> option set to
                    <emphasis>true</emphasis>, the calling query continues executing until it tries to access the value
                of the variable bound to the result of the <function>xdmp:spawn</function>, at which point if the
                    <emphasis>spawned</emphasis> query has completed executing, the result is available, however if it
                has not completed then the main query thread blocks and waits for the <emphasis>spawned</emphasis> query
                to complete and provide the result <biblioref linkend="bib_marklogic_xdmp-spawn"/>. Similarly to BaseX
                and eXist-db, MarkLogic also provides mechanisms for the scheduling of XQuery execution through its
                offline batch processing framework called <acronym xml:id="acr_CPF" linkend="bacr_CPF">CPF</acronym>
                    (<phrase xml:id="bacr_CPF" linkend="acr_CPF">Content Processing Framework</phrase>) <biblioref linkend="bib_marklogic_cpf"/>, and a set of XPath extension functions such as
                    <function>admin:group-add-scheduled-task</function>
                <biblioref linkend="bib_marklogic_admin-group-add-scheduled-task"/>. </para>
            <para>MarkLogic's <emphasis>value future</emphasis> is intriguing in its nature, albeit proprietary. The concept of Futures appear in several programming languages,
                but unlike other languages (e.g., Java or C++11), MarkLogic's implementation provides no explicit call to <emphasis>get</emphasis> the value of the future (possibly with a timeout), instead
                the <emphasis>wait</emphasis> and/or <emphasis>get</emphasis> happen as one implicitly when accessing the value through its variable binding.</para>
            <para>MarkLogic clearly documents where it allows side effects from within XQuery. There are two distinct
                types of side effects within MarkLogic, state changes that happen within the scope of the XQuery itself,
                and those state-changes which are external to the XQuery. For use within the scope of an XQuery,
                MarkLogic provides an XPath extension function <function>xdmp:set</function>, which explicitly states
                that it uses <quote>changes to the state (side effects)</quote>
                <biblioref linkend="bib_marklogic_xdmp-set"/> to modify the value of a previously declared variable,
                thus violating the formal semantics of XPath <biblioref linkend="bib_xpath20_fs"/>. For modifying state
                external to an XQuery, MarkLogic provides a series of XPath extension functions for updating nodes and
                managing documents within the database. Similarly to BaseX, these extension functions do not cause
                side effects by immediate application, and are invisible to both the executing query and concurrently
                executing queries <biblioref linkend="bib_marklogic_visibility"/>. Unlike BaseX, MarkLogic does not
                implement the XQuery Update specification, but similarly it utilizes a <acronym linkend="bacr_PUL">PUL</acronym>, likewise leading to a process whereby the updates are applied to the database after
                the query completes and the transaction is committed, thus making the updates visible to subsequent
                transactions. </para>
            <para>Whilst MarkLogic utilizes both a well defined transaction isolation model and deferred updates to mostly avoid side effects within an executing XQuery, we suspect
                that the use of <function>xdmp:set</function> likely places some limitations on possible query optimisations that could be performed.</para>
            <para>We have focused on MarkLogic's XQuery implementation, but it is worth noting that MarkLogic also implements XSLT 2.0. 
                All of MarkLogic's XPath extension functions (e.g., <function>xdmp:set</function> and <function>xdmp:insert-*</function>) are also available from its XSLT processor, and are subject to the
                same transactional mechanisms as the XQuery processor; therefore our findings are equally applicable to running either XQuery or XSLT on MarkLogic.</para>
        </sect2>

        <sect2>
            <title>Saxon</title>
            <para>Saxon-EE utilises parallel processing in certain specific instances <biblioref linkend="bib_kay15"/>.
                By default the parsing of input
                files for the <function>fn:collection</function> function is multithreaded, as is the processing of
                    <code>xsl:result-document</code> instructions. Note that the outputs produced by multiple
                    <code>xsl:result-document</code> instructions are quite independent and never need to be merged; so
                while this does allow parallel execution of user code and requires careful implementation of features
                such as try/catch and lazy evaluation, the fact that there is a "fork" with no "join" simplifies things
                a lot. Furthermore, multi-threading of <code>xsl:for-each</code> instructions using a MapReduce approach
                can be enabled by the user, by setting the <code>saxon:threads</code> extension attribute to specify the
                number of threads to be used.</para>
            <para>Saxon-EE allows use of a number of extension functions with side effects, including those in the
                EXPath File and Binary modules. Similar to the BaseX handling, the Saxon compiler recognises such
                expressions as causing side effects, and takes a pragmatic approach in attempting to avoid aggressive
                optimisations which could otherwise disrupt the execution order. Usually instructions in an XSLT
                sequence constructor will be executed sequentially in the order written, but deviation can be caused by
                the compiler through lazy evaluation or loop lifting; and this is where problems can arise when
                side effects are involved. Such optimisations can cause the side effect to happen the wrong number of
                times (never, or too often), or at the wrong time. It is relatively straightforward to prevent such
                optimisations for static calls to side-effecting functions, but cannot always be guaranteed for more
                nested calls, as "side-effecting" is not necessarily recognised as a transitive property. For instance,
                a function or template which includes a call to a side-effecting function may not itself be recognised
                as side-effecting. So it is always recommended that side-effecting XPath expressions are "used with
                care". One mechanism which gives the XSLT author better control when using side-effecting expressions,
                is the recently added extension instruction <code>saxon:do</code>. It is similar to the
                    <code>xsl:sequence</code> instruction, but is designed specifically for use when invoking XPath
                expressions with side effects. In contrast to <code>xsl:sequence</code>, when using
                    <code>saxon:do</code> any result is always discarded, and the processor ensures that instructions in
                the sequence constructor are always evaluated sequentially in the order written, avoiding any reordering
                from optimisations.</para>
            <para>As previously mentioned, for use with the Saxon-JS runtime XSLT processor, a number of <phrase linkend="acr_IXSL">Interactive XSL</phrase> extension instructions and functions are available. To
                enable non-blocking (asynchronous) HTTP requests and document fetching, the
                    <code>ixsl:schedule-action</code> instruction is provided. Attributes on the instruction are used to
                specify an HTTP request, or document URI, and the associated HTTP request is then executed in a new
                concurrent thread. The callback, for when an HTTP response is returned or the document is fetched (or an
                HTTP error occurs), is specified using the single permitted <code>xsl:call-template</code> child of the
                    <code>ixsl:schedule-action</code> instruction. When the <code>document</code> attribute has been
                used, the called template can then access the document(s) using the <function>fn:doc</function> or
                    <function>fn:doc-available</function> functions; the document(s) will be found in a local cache and
                will not involve another request to the server. When using the <code>http-request</code> attribute, the
                HTTP response is supplied as the context item to the called template, in the form of an XDM map.
                Alternatively, <code>ixsl:schedule-action</code> can simply be used to start concurrent processing for
                any action, by using just the <code>wait</code> attribute (with a minimal delay). Note that while this provides a
                "fork", there is no "join", and it is up to the developer to avoid conflicts caused by
                side effects.</para>
            <para>To be able to write interactive applications directly in XSLT, it is necessary to make use of
                side effects, for example to dynamically update nodes in the HTML page. Almost all of the <acronym linkend="bacr_IXSL">IXSL</acronym> extension instructions and functions (such as
                    <code>ixsl:set-attribute</code> and <code>ixsl:set-property</code> which are used to set attributes
                on nodes and properties on JavaScript objects respectively) have (or may have) side effects. Note that
                Saxon-JS runs precompiled XSLT stylesheets, called <acronym xml:id="acr_SEF" linkend="bacr_SEF">SEF</acronym>s (<phrase xml:id="bacr_SEF" linkend="acr_SEF">Stylesheet Export Files</phrase>)
                generated using Saxon-EE. As described above, during compilation in Saxon-EE, such side-effecting
                functions and instructions are internally marked as such to prevent optimisations from disrupting the
                intended execution order.</para>
        </sect2>

        <sect2 xml:id="sect_xq-promise">
            <title>xq-promise</title>
            <para>Whilst xq-promise <biblioref linkend="bib_wright16"/> is not an implementation of XQuery or XSLT, it is the first known non-vendor specific proposal for a module of XPath extension functions
                by which XPDL implementations can offer concurrent processing from within an XPDL. It is valuable to review this proposal as theoretically it
                could be implemented by any XPDL implementation, at present we are only aware of a single implementation for BaseX <biblioref linkend="bib_xqpromise"/>.</para>
            <para>xq-promise first and foremost provides a set of XPath extension functions which were inspired by
                jQuery's Deferred Object utility, it claims to implement the <quote>promise pattern</quote> (see <xref linkend="sect_promises_and_futures"/>), and focuses on the concept of deferring execution. In its
                simplest form, the <function>promise:defer</function> function takes two parameters: a function of
                variable arity, and a sequence of arguments of the same arity as the function. Calling
                    <function>promise:defer</function> returns a new zero arity function called a
                <quote>promise</quote>, this <emphasis>promise</emphasis> function encapsulates the application of the
                function passed as a parameter to the arguments passed as a parameter. The encapsulation provided by the
                promise function <emphasis>defers</emphasis> the execution of the encapsulated function. The promise
                function also serves to enable chaining further actions which are dependent on the result of executing
                the deferred function, such further actions are also deferred. The chaining is implemented through
                function composition, but is opaque to the user who is provided with the more technically accessible
                functions <function>promise:then</function>, <function>promise:done</function>,
                    <function>promise:always</function>, <function>promise:fail</function>, and
                    <function>promise:when</function>.</para>
            <para>The functions provided by xq-promise discussed so far allow a user to describe a chain of related actions, where callback functions,
                for example established through <function>promise:then</function>, can be invoked when another function completes with success or failure. Considered in isolation
                these functions do not explicitly prescribe any asynchronous or concurrent operation. To address this, xq-promise secondly provides an XPath extension
                function named <function>promise:fork-join</function> based on the Fork-join model of concurrency. This functions takes as a parameter a sequence of promise functions,
                which may then be executed concurrently.
                The <function>promise:fork-join</function> function is a blocking function, which is quite different from those of BaseX, eXist-db, MarkLogic, or Saxon, which are
                all non-blocking. Rather than scheduling a query for concurrent execution and then returning to the main query so execution can continue, when <function>promise:fork-join</function>
                is invoked <emphasis>n</emphasis> query sub-processes are <emphasis>forked</emphasis> from the main query which
                then waits for these to complete, at which point the results of the sub-processes are <emphasis>joined</emphasis> together and returned as the result of the function call.
            </para>
            <para>An important insight we offer is that whilst sharing some terminology with implementations in other
                languages (particularly JavaScript likely due to building upon jQuery's Deferred Object) the
                    <emphasis>promise</emphasis> concept used in xq-promise is subtly different <biblioref linkend="bib_retter_xqpromise18"/>. JavaScript Promises upon construction immediately execute the
                function that they are provided <biblioref linkend="bib_mdn_promise-syntax"/>
                <biblioref linkend="bib_ecma262"/>, whereas an xq-promise is not executed until either
                    <function>promise:fork-join</function> is used or the promise function is manually applied by the
                user. Conceptually the xq-promise promises appear to be at odds with the fork-join approach, as once a
                promise has been constructed, it is likely that useful computation could have been achieved in parallel
                to the main thread by executing the promise(s) before reaching the fork-join point. The construction of
                a JavaScript Promise requires an <emphasis>executor</emphasis> function, which takes two parameter
                functions, a resolve function and a reject function. The executor must then call one of these two
                functions to signal completion. When constructing a promise with xq-promise, completion is instead
                signalled by the function terminating normally, or raising an XPath error. This may appear to be just
                syntactical differences, but the distinction is important: the JavaScript approach allows an error value
                to explicitly be returned upon failure in a functional manner, the xq-promise approach relies instead on
                    <function>fn:error</function>... which is a side effect! </para>
            <para>On the subject of xq-promise and side effects, xq-promise constructs chains of execution where each
                step has an dependency on the result of the preceding step. On the surface this may appear similar to
                how IO Monads (see <xref linkend="sect_haskell_io_monad"/>) compose. The composition of xq-promise
                through is much more limited, and whilst it ensures some order of execution, its functional semantics
                are likely not strong enough to ensure a total ordering of execution. </para>

        </sect2>
        <sect2>
            <title>Conclusion of Implementers Survey</title>
            <para>Our conclusion from this survey is twofold. Firstly, all surveyed implementations offer some varying
                proprietary mechanism for performing asynchronous computations from within a main XPDL thread of
                execution. A standardised approach is evidently missing from the W3C defined XPDLs, but a requirement
                has been demonstrated by implementations presumably meeting a technical demand of their users of XPDLs.
                Secondly, none of the XPDL implementations which we examined adhere strictly to the functional
                processing semantics required by XPath and/or the respectively implemented XPDL specification. Instead
                each implementation to a lesser or greater extent offers some operations which cause side effects. Most
                implementations appear to have taken a pragmatic approach to deliver the features that their users
                require, often sacrificing the advantages of a pure functional approach to offer a likely more familiar
                imperative programming model.</para>
        </sect2>
    </sect1>
    <sect1 xml:id="sect_survey-non-xpdls">
        <title>Solutions offered for non-XPDLs</title>
        <para>This survey provides a brief review of several options for non-XPDLs that provide solutions for both
            concurrent and/or asynchronous execution, and how side effects are managed or avoided. This is not intended
            as an exhaustive survey, rather the options surveyed herein were subjectively chosen for their variety. </para>

<!-- TODO what about Lisp, how does that handle side effects? -->
        
        <sect2>
            <title>Actor Model</title>
            <para>The Actor Model defines a universal concept, the Actor, which receives messages and undertakes computation in response to a message. Each Actor may also asynchronously send
                messages to other Actors. A system is typically made up of many of these Actors <biblioref linkend="bib_hewitt73"/>. Actor systems are another class of embarrassingly parallel problem, 
                as the messages sent between actors are immutable, there is no shared-mutable state to synchronize access to, and so each Actor can run concurrently.
            </para>
            <para>The Actor Model by itself is not enough to clearly describe, manage, or eliminate side-effectful computation, however by nature of its message passing approach
                it does eliminate the side effects of modifying the shared-state for communication between concurrent threads of execution which is often found in non-actor systems.
                Through encapsulation, actors may also help to reason about programs with side effects. Systems utilising actors are often built in such a manner that
                each task specific side-effectful computation is isolated and encapsulated within a single Actor. For example, within an actor system there may only be a single
                Actor which handles a particular file I/O, then since each Actor likely runs as a separate process, the file I/O has been isolated away from other computation.
            </para>
            <para>The Erlang programming language is possibly the most well known Actor Model like implementation, wherein Actors are known as 
                processes <biblioref linkend="bib_armstrong07"/>. Erlang itself makes no additional efforts to manage side effects, and additional synchronization primitives
                are often employed. Within the <acronym xml:id="acr_JVM" linkend="bacr_JVM">JVM</acronym> (<phrase xml:id="bacr_JVM" linkend="acr_JVM">Java Virtual Machine</phrase>)
                ecosystem, the Akka framework is available for both Java and Scala programming languages <biblioref linkend="bib_akka_actors"/>. Java as a non-functional language
                makes no attempts at limiting side effects. Meanwhile, whilst Scala is often discussed as a functional language and does provide many functional programming constructs, it
                is likely more a general purpose language, as mutability and side effects are not restricted, and it is quite possible to write imperative Scala code. Actor systems
                are also available for many other programming languages <biblioref linkend="bib_wikipedia_actormodel"/>, although they do not seem to have gained the same respective
                popularity as Erlang or Akka.</para>
        </sect2>
        
        <sect2>
            <title>Async/Await</title>
            <para>The Async/Await concept was first introduced in C#, inspired by F#'s <emphasis>async workflows</emphasis> <biblioref linkend="bib_hejlsberg10"/>,
                which was in turn inspired by Haskell's Async Monad <biblioref linkend="bib_syme07"/> <biblioref linkend="bib_marlow12"/> (see <xref linkend="sect_haskell_io_monad"/>).
                Async/Await provides syntax extensions to a programming language in the form of the <code>async</code> and <code>await</code> keywords. Async/Await allows
                a developer to write a program using a familiar synchronous like syntax but easily achieve asynchronous operation of parts of the program.</para>
            <para>
                Async/Await adds no further processing semantics for concurrency or managing side effects over that of Promises (see <xref linkend="sect_promises_and_futures"/>),
                which are often used to implement Async/Await. Async/Await may be thought of as syntactic sugar for utilising a Promise based implementation, and has
                recently become very popular with JavaScript developers <biblioref linkend="bib_gaafar17"/> <biblioref linkend="bib_kantor19"/>.
            </para>
        </sect2>
        
        <sect2>
            <title>Coroutines</title>
            <para>Coroutines are a concept for cooperative multitasking between two (or more) processes within a program. One process within an application, Process A, may
                <emphasis>explicitly</emphasis> yield control to another process, Process B. When control is transferred, the state of Process A is saved, the current state of Process B is restored (or a new state created
                if there is no previous state), and Process B continues until it <emphasis>explicitly</emphasis> yields control back to Process A or elsewhere <biblioref linkend="bib_conway6307"/>.
            </para>
            <para>Like Actors, the impact of side effects of impure functions can be somewhat isolated within a system by encapsulating them in distinct coroutines. Otherwise Coroutines provide
                no additional facilities for directly managing side effects, and global state is often shared between them. Unlike Actors, Coroutines are often executed concurrently by means of explicitly yielding control.
                Without additional control structures, coroutines typically operate on a single-thread, one exception is Kotlin's Coroutines which can be structured to execute
                concurrently across threads <biblioref linkend="bib_kotlin18"/>.
            </para>
            <para>Some implementations of Coroutines, such as those present in Unity <biblioref linkend="bib_unity18"/>, or JavaScript <biblioref linkend="bib_cooper12"/>, attempt to bring a familiar synchronous
                programming style to the developer. These implementations typically have a coroutine <emphasis>yield</emphasis> multiple results to the caller, as opposed
                to yielding control. This masks the cooperative multitasking aspect from the developer and presents the return value of a coroutine as an iterable collection of results.
            </para>
        </sect2>

<!-- TODO do we need a quick section on fork/join as we have BaseX and xq-promise both using it? ...if so we should xref -->

        <sect2 xml:id="sect_haskell_io_monad">
            <title>IO Monads</title>
            <para>Haskell is a statically typed, non-strict, pure functional programming language. The <emphasis>pure</emphasis> aspect means that every function in Haskell
                must be <emphasis>pure</emphasis>, that is to say akin to a mathematical function in the sense that mathematical functions cannot produce side effects.
                Even though Haskell prohibits side effects by design, it still enables developers to perform I/O and compute concurrently. This seemingly impassable juxtaposition
                of academic purism and real-world engineering need is made possible by its IO Monad <biblioref linkend="bib_jones92"/>.
                Haskell trialled several other approaches in the past, including streams and continuations, before the IO Monad 
                won out as it facilitated a more natural imperative programming style <biblioref linkend="bib_hudak07"/>.
            </para>
            <para>In Haskell, any function that performs I/O must return an IO type which is monadic. This IO type represents an IO action which has not yet happened. For example
                if you have a function that reads a string from a file, that function does not directly return a <code>String</code>,
                instead it returns an <code>IO String</code>. This is not the result of reading a line from the file, instead it can be thought of as an action
                that when <emphasis>executed</emphasis> will read a line from the file and return a <code>String</code>. These IO actions describe the I/O that you wish 
                to perform, but critically defer its execution. The <code>IO</code> actions adhere to <emphasis>monad laws</emphasis> which allow them to be
                composed together. For example given two IO actions, one that reads a file and one that writes a file, they could be composed together
                into a single IO action which first reads a file and then writes a file, e.g. a copy file IO action.</para>
            
<!-- TODO should we also relate the two paragraphs below to PUL (mentioned briefly in BaseX section already)... or should we put it in the Survey Conclusion section?
                    - An IO Action is similar to a PUL's Update Primitive
                    - the fact that `main` returns an IO, is not dissimilar to an XQuery Update returning both XDM and a PUL
            -->
            
            <para>Importantly, the formal definition for an <code>IO</code> type is effectively <code>IO a = World -&gt; (a, World)</code>.
                That is to say that an IO is a state transformation
                function that takes as input the current state of the world, and produces as the result both a value and a new state of the new world.
                The <code>World</code> is a purely Abstract Data Type, that the Haskell programmer cannot create. 
                The important thing
                to note here is that the <code>World</code> is threaded through the IO function. When multiple IO actions are composed together
                using monadic application, such as <emphasis>bind</emphasis>, the <code>World</code> output from a preceding function will
                be fed to the input of the succeeding function. In this manner the <code>World</code> will be threaded through the entire chain of IO actions.</para>
            <para>A Haskell program begins by executing a function named <code>main</code> that must return an IO, it is typed as <code>mainIO :: IO ()</code>. Haskell knows how
                to execute the IO type function that the main function returns. Naively one can think of this as Haskell's runtime creating the <code>World</code> and then calling our IO with it
                as an argument to execute our code; in reality the Haskell compiler optimises out the <code>World</code> during compilation whilst still ensuring the correct execution
                order.
            </para>

            <para>By using IO Monads which defer rather than perform I/O, all Haskell functions are pure, and so a Haskell program at evaluation time exhibits no side effects whatsoever,
                instead finally evaluating to an <code>IO ()</code>, i.e. a state transformation function upon the world. As the developer has used monadic composition of their IO actions,
                this has implicitly threaded the <code>World</code> between them, in the order the developer would
                expect (i.e. in the order of the composition), therefore the state transformation also ensures that
                the functions are executed in the expected/correct order. At execution time, the machine code representation of the Haskell program is run by a CPU which is side-effecting
                in nature, and the IO action's side effects are unleashed.
            </para>
            <blockquote>
                <attribution>from "State in Haskell", by John Launchbury and Simon Peyton Jones</attribution>
                <para>It is possible to encapsulate stateful computations so that they appear to the
                rest of the program as pure (stateless) functions which are guaranteed by the
                type system to have no interactions whatever with other computations, whether
                stateful or otherwise (except via the values of arguments and results, of course).</para>
            </blockquote>
           
            <para>
                Haskell provides further functions for concurrency, but critically these also return IO actions. One such example is <function>forkIO</function> with the signature
                <code>forkIO :: IO () -&gt; IO ThreadId</code> <biblioref linkend="bib_haskell10"/>. The purpose of forkIO is to execute an IO in another thread, so it takes an IO as an argument, and returns an IO.
                The important thing to remember here, is that calling the forkIO function does not create a new thread and execute an IO, rather it returns an IO action which describes and defers such behaviour.
                Later when this IO action is finally executed at run-time, the thread will be created at the appropriate point within the running program.
                There are also a number of other higher-level abstractions for concurrency in Haskell, such as Async <biblioref linkend="bib_marlow12"/>, and whilst such abstractions
                <emphasis>may</emphasis> introduce additional monads, they ultimately all operate with IO to defer any non-pure computation. One final point on the IO Monad, is to
                mention that concurrently executing I/O actions, may at runtime produce side effects that conflict with each other. The IO Monad is only strong enough to ensure
                correct operation within a single thread of execution, its protections do not cross thread-boundaries. To guard against problems with concurrent modifications
                additional synchronisation is required. Haskell provides additional libraries of such functions and types for working with synchronization primitives,
                many of which themselves produce IO actions!
            </para>
            <para>Monads are by no means limited to Haskell, and can likely be used in any language which supports higher-order functions. The preoccupation with Haskell is
                centred around how it uses Monads to ensure a pure language in the face needing to perform I/O.
                Several libraries exist which attempt to bring the IO Monad concept to other programming languages, this seems to have been most visible within the
                Scala ecosystem, where there are now at least five differing established libraries <biblioref linkend="bib_goes17"/>. Whilst all of these efforts are
                admirable and bring new mechanisms for managing side effects, they all have one weakness which Haskell does not: in Haskell one is forced to ensure
                that the entire program is pure, because the main function must return an IO. The runtimes of other languages are not structured in this way,
                and so these IO Monad libraries are forced to rely on workarounds to evaluate the IO. These rely on the user structuring their
                program around the concept of an IO, and only evaluating that IO as the last operation in their program. For example Monix Task <biblioref linkend="bib_monix18"/>, where the user must
                eventually call <function>runUnsafeSync</function> to evaluate the IO, describes the situation as thus:
                <blockquote>
                    <attribution>
                        <personname>
                            <firstname>Alexandru</firstname>
                            <surname>Nedelcu</surname>
                        </personname>
                    </attribution>
                    <para>In general prefer to ... structure your logic around asynchronous actions in a non-blocking way. But in case you're blocking
                        only once, in <function>main</function>, at the "edge of the world" so to speak, then it's OK.</para>
                </blockquote>
            </para>
        </sect2>

        <sect2 xml:id="sect_promises_and_futures">
            <title>Promises and Futures</title>
            <para>There may be some confusion over the differences between the computer science terms
                    <emphasis>Promise</emphasis>, <emphasis>Future</emphasis>, or even <emphasis>Eventuals</emphasis>.
                However, these terms are academically synonymous, as perhaps best explained by Baker and Hewitt, the
                fathers of the term <emphasis>Future</emphasis>
                <biblioref linkend="bib_baker77"/>: <blockquote>
                    <attribution>Henry G. Baker Jr. and Carl Hewitt</attribution>
                    <para>the mechanism of futures, which are roughly Algol-60 "thunks" which have their own evaluator
                        process ("thinks"?). (Friedman and Wise <biblioref linkend="bib_friedman76"/> call futures
                        "promises", while Hibbard <biblioref linkend="bib_hibbard76"/> calls them "eventuals".)</para>
                </blockquote> The confusion likely comes from implementations that offer both Future and Promise
                abstractions to developers looking for safer concurrency facilities, yet use differing
                terminology and provide vastly different APIs. Two examples of extreme variation of terminology, are the
                Scala and Clojure programming languages, which each define Future and Promise as distinct classes. The
                Scala/Clojure Future class is much more like the computer science definition of Future/Promise which
                models computation; whereas the Scala/Clojure Promise class serves a very different purpose, primarily
                as a memorized data provider for completing a Future class. We are strictly interested in the computer
                science definition of Promise and Future, and herein will refer to them singly as Promise.</para>
            
            <para>A Promise represents a value which may not yet have been computed. Typically when creating a Promise a computation is immediately started asynchronously and returns a Promise.
                In implementation terms, a Promise is a reference which will likely take the form of an object, function, or integer.
                At some point in the future when the asynchronous computation completes, the Promise is fulfilled with the result
                of the computation which may be either a value or an error. Promises provide developers with an abstraction for concurrent programming, but whether
                that is executed via cooperative or preemptive multi-tasking is defined by the implementation. Promises by themselves provide no mechanism
                for avoiding side effects as they are likely eagerly evaluated, with multiple promises being unordered with respect to execution.</para>
            
            <para>Some implementations, for example those based on Promise/A+ like JavaScript, allow
                you to functionally compose Promises together <biblioref linkend="bib_denicola12"/>. This functional composition can allow you to chain together side-effecting functions
                which are encapsulated within Promises, thus giving an explicit execution order, in a manner not dissimilar to Haskell's IO Monad (see <xref linkend="sect_haskell_io_monad"/>). Unlike Haskell's IO Monad however, this doesn't
                suddenly mean that your application is pure: remember that JavaScript Promises are eagerly evaluated. It does though offer a judicious JavaScript developer some measure to ensure the correct
                execution order of her impure asynchronous code.
            </para>

        </sect2>
        
        <sect2>
            <title>Reactive Streams</title>
            <para>Reactive Streams enable the composition of a stream of computation, where the Publisher, Subscriber, or a Processor in the stream (which act as
                both Subscriber and Publisher), may operate asynchronously <biblioref linkend="bib_reactive17"/>. A key characteristic of Reactive Streams is that of <emphasis>back-pressure</emphasis>, a form of flow control which 
                can prevent slower Subscribers from being overwhelmed by faster asynchronous Producers. This built-in back-pressure facility appears to be unique to
                Reactive Streams, and would otherwise have to be manually built by a developer atop other concurrency mechanisms.</para>
            <para>The Reactive Streams initiative itself just defines a set of interfaces and principles for Reactive Stream implementations, it is up to the implementations
                to provide mechanisms for controlling concurrent and parallel processing of streaming values. Typically implementations provide mechanisms
                for parallelising Processors within a stream, or splitting a stream into many asynchronously executing streams which are later resolved back
                to the main stream.</para>
            <para>Reactive Streams offers little explicitly to help with side effects, however if we consider that a data flow within a non-concurrent stream
                is always downwards, then streams do provide an almost Monadic-like mechanism for composing processing steps where the order of execution becomes explicit.
                Likewise, if one was to ensure that the data that is passed from one step to another is immutable, then when there are concurrent or asynchronous Subscribers,
                there can be no data-driver side effects between them as the data provided by the publisher was immutable, meaning that any changes to the data by
                a subscriber are isolated to a localised copy of the data.</para>
            <para>Examples of Reactive Streams implementations that support concurrent and parallel processing at this time include: RxJava, Akka Streams, Monix,
                Most.js, and Reactive Streams .NET#</para>  
        </sect2>
        
        <sect2>
            <title>Conclusion of non-XPDL Solutions Survey</title>
            <para> Our survey shows several different options for concurrent/parallel programming. It is possible to
                build the same application using any of these options, but each offers a different approach and syntax
                for isolating and managing concurrently executing processes. As well as the underlying computer science
                principles of each option, the libraries or languages that implement these options can vary between
                Cooperative Multitasking and Preemptive Multitasking. Coroutines, Async/Await, and Promises are
                particularly well suited to Cooperative Multitasking systems due to their explicit demarcation of
                computation boundaries, which can be used to yield the CPU to another process. Likely this is why these
                options have been adopted in the JavaScript community, where JavaScript Virtual Machines are frequently
                designed as cooperatively multitasking systems utilising an event loop <biblioref linkend="bib_eventloop18"/>.</para>
            
            <para>We find that the IO Monad is the only surveyed option that is specifically designed to manage computational side effects in a functional manner.
                This is likely due to the fact that the IO Monad approach was explicitly developed for use in a non-strict purely functional language, i.e. Haskell, whereas
                all of the other approaches are more generalised, and whilst not explicitly limited to imperative languages are often found in that domain.</para>
            
            <para>Of all the approaches surveyed, to the best of our knowledge, only the development of a Promise-like
                approach has been realised for <acronym linkend="bacr_XPDL">XPDL</acronym>s, namely xq-promise (see
                    <xref linkend="sect_xq-promise"/>). It seems likely that at least aspects of the IO Monad approach
                (such as that demonstrated by Monix), or Reactive Streams options, could be implemented by utilising
                XPath extension functions and a written specification of concurrent implementation behaviour, without
                resorting to proprietary XPath syntax extensions. Conversely, whilst an XPath function based
                implementation could likely be devised, both Async/Await and Coroutines would likely benefit by
                extending the XPath language with additional syntax. </para>

<!-- TODO relate Monads to PUL or do it above in Monad section? -->
            
            <para>In conclusion, we believe that an IO Monad exhibits many of the desirable properties that we set out
                to discover in <xref linkend="sect_our-requirements"/>. It has strong pure functional properties, strict
                isolation of side effects, and acts as a building block for constructing further concurrent/parallel
                processing. Therefore we have chosen to use this as the basis for a solution to handle side effects and
                sequential or concurrent processing in XPDLs. </para>
        </sect2>

    </sect1>
    <sect1 xml:id="sect_expath_tasks">
        <title>EXPath Tasks</title>
        <para>Herein we describe EXPath Tasks, a module of extension XPath functions for performing <emphasis>Tasks</emphasis>.
            These functions have been designed to allow an XPDL developer to work with both side effects and
            concurrency in a manner which appears imperative but is functionally pure, and therefore does not require processors
            to sacrifice optimisation opportunities.
        </para>
        <para>The specification of the functions and their behaviour is defined in <xref linkend="apdx_tasks-module"/>.
            We have also developed four reference implementations: <variablelist>
                <varlistentry>
                    <term>XQuery</term>
                    <listitem>
                        <para>task.xq is written in pure XQuery 3.1 with no extensions. It implements all functions,
                            however all potentially asynchronous operations are executed sychronously. The source code
                            is available from <link xlink:href="https://github.com/adamretter/task.xq"/>.</para>
                    </listitem>
                </varlistentry>
                <varlistentry>
                    <term>XSLT</term>
                    <listitem>
                        <para>task.xsl is written in pure XSLT 3.0 with no extensions. There is a lot of code overlap
                            with task.xq, since much is actually XPath 3.1. Like task.xq, it implements all functions,
                            however all potentially asynchronous operations are executed sychronously. The source code
                            is available from <link xlink:href="https://github.com/saxonica/expath-task"/>.</para>
                        <!-- TODO DEBBIE finalize link -->
                    </listitem>
                </varlistentry>
                <varlistentry>
                    <term>Java</term>
                    <listitem>
                        <para>An implementation of EXPath Tasks for XQuery in eXist-db. The source code is available
                            from <link xlink:href="https://github.com/eXist-db/exist/tree/expath-task-module-4.x.x/extensions/expath/src/org/expath/task"/>.</para>
                    </listitem>
                </varlistentry>
                <varlistentry>
                    <term>JavaScript</term>
                    <listitem>
                        <para>An implementation of EXPath Tasks for XSLT in Saxon-JS.</para>
                    </listitem>
                </varlistentry>
            </variablelist>
        </para>
        <sect2>
            <title>The Design of EXPath Tasks</title>
            <para>From the findings of our survey on non-XPDL solutions (see <xref linkend="sect_survey-non-xpdls"/>), we felt that the best fit for our
                requirements (see <xref linkend="sect_our-requirements"/>) was that of developing a module of XPath Functions that could both ensure
                the correct execution ordering of side-effecting functions, and provide facilities for asynchronous programming.</para>
            
            <para>We decided to adopt the principles of the IO Monad, as we have previously identified it as providing the most comprehensive approach to managing non-deterministic
                functions in a pure functional language. Our design was heavily influenced by both Haskell's IO <biblioref linkend="bib_jones92"/> and Async
                <biblioref linkend="bib_marlow12"/> packages, and to a lesser extent by Monix's Task <biblioref linkend="bib_monix18"/>.</para>
            
            <para>Our decision to develop a module of extension functions rather than grammar extensions, was influenced by a previous monadic approach for
                XQuery, called <emphasis>XQuery!</emphasis>, which utilized grammar extensions but failed to gain adoption <biblioref linkend="bib_ghelli06"/>.</para>
            
            <para>An astute reader may raise the question of why we didn't attempt a translation of IO actions to <acronym linkend="bacr_PUL">PUL</acronym> Update Primitives.
                The issue that we saw is that a <acronym linkend="bacr_PUL">PUL</acronym> is an opaque collection, which cannot be computed over. With XQuery Update there is no mechanism for directly working with the result
                of a previous Update Primitive. We required a solution that was applicable to general computation, so we focused on a task based approach. Of course there is the
                concern that we would have also had to adopt much of the XQuery Update specification to make this work in practice. For XPDLs that are not derived from XQuery
                this may have been prohibitive to adoption. However, we see no reason why further work could not examine the feasibility of <emphasis>lifting</emphasis> a Task to an Update Primitive.</para>
            
            <sect3>
                <title>Abstract Data Types</title>
                <para>Haskell's IO Monad makes use of an <acronym xml:id="acr_ADT" linkend="bacr_ADT">ADT</acronym> (<phrase xml:id="bacr_ADT" linkend="acr_ADT">Abstract Data Type</phrase>)
                    to represent the <emphasis>World</emphasis> which it is transforming. The beauty of using an <acronym linkend="bacr_ADT">ADT</acronym> here is that the Haskell programmer cannot themselves instantiate
                this type<footnote>
                        <para>Haskell does provide an <code>unsafePerformIO</code> function which can <emphasis>conjure</emphasis> the world up, and execute the IO.
                    However, such behaviour is considered bad practice in the extreme.</para>
                    </footnote>, which makes it impossible to execute IO directly. Instead the Haskell compiler
                    is responsible for compiling the application in such a manner that the IO will be implicitly executed at runtime.</para>
                <para>Recall that the <type>IO</type> type is really a state transformation function, with the signature
                    <programlisting language="haskell">
<type>IO a</type> = <parameter>World</parameter> -&gt; <returnvalue>(a, World)</returnvalue>
                    </programlisting>
                    To create an equivalent function for XPDLs we need some mechanism for modelling the <type>World</type> <acronym linkend="bacr_ADT">ADT</acronym>.
                    Unfortunately, without requiring <emphasis>Schema Awareness</emphasis>, the <acronym linkend="bacr_XDM">XDM</acronym> type system is sealed. It is
                    not possible to define new types abstract or otherwise within XDPLs.
                </para>
                <para>To remain within the XPDL specifications we must therefore define the <type>World</type> using some non-abstract existing type.
                    Unfortunately, this means that the developer can also instantiate the <type>World</type> and potentially execute the IO.
                    We developed an initial prototype <biblioref linkend="bib_retter19"/> where we modelled the <type>World</type> simply as
                    an XDM Element named <code>io:realworld</code>, thus our XPath IO type function was defined such: <programlisting language="xquery">
declare function io:IO($realworld as element(io:realworld)) as item()+
                    </programlisting>
                    Note the <type>item()+</type> return type: in XPath there is no tuple type so we have to use a less strict definition than
                    we would prefer. This sequence of items will have 1+<emphasis>n</emphasis> items, where the head of the sequence is always the new state
                    of the world (i.e. the XDM element named <code>io:realworld</code>), and the tail of the sequence is the result of executing the IO.</para>
                <para>Implementations written for XPDLs in non-XPDLs could likely enforce stronger semantics by using some proprietary type outside of the XDM
                    to represent the <code>World</code> which is un-instantiable from the XPDL.</para>
                <para>Like Haskell's <acronym xml:id="acr_GHC" linkend="bacr_GHC">GHC</acronym> (<phrase xml:id="bacr_GHC" linkend="acr_GHC">Glasgow Haskell Compiler</phrase>),
                    whether there really is a <code>World</code> that is present in the application at execution time or not is an implementation detail.
                    Certainly it is crucial that the <code>World</code> is threaded through the chain of IO actions at evaluation time to ensure ordering, but implementations
                    are free to optimise the world away as long as they preserve ordering.</para>
            </sect3>

            <sect3>
                <title>Typing a Task</title>
                <para>Ultimately we adopted the name <emphasis>Task</emphasis> instead of <emphasis>IO</emphasis> to represent our
                    embracement of more than just I/O.</para>
                <para>The first version of our Task Module was developed around the type definition of a <code>Task</code> as: <programlisting language="xquery">
declare function task:task($realworld as element(adt:realworld)) as item()+
                    </programlisting>
                    We quickly realised that using this module led to verbose syntax, and that the function syntax obscured the ordering of chains; the ordering of task execution being the
                    most deeply nested and then extending outwards:
                    <figure>
                        <title>Example of Tasks using Function based syntax</title>
                        <programlisting language="xquery">
task:fmap(
    task:fmap(
        task:value("hello"),
        upper-case#1
    ),
    concat(?, " adam")
)
                        </programlisting>
                    </figure>
                </para>
                <para>To provide a more natural imperative syntax, we realised that instead of modelling a Task as a function type, we could model it as an XDM Map of functions which
                    can be <emphasis>applied</emphasis>. An XDM Map is itself a function from its key to its value. By modelling a Task as Map, we could use the encapsulation concept from
                    <acronym xml:id="acr_OOP" linkend="bacr_OOP">OOP</acronym> (<phrase xml:id="bacr_OOP" linkend="acr_OOP">Object Oriented Programming</phrase>)
                    to place functions in the Task (Map), that act upon that task. Each function that we previously defined that operated upon a Task, we recreated as a function
                    inside the Map which operates on the Task represented by the Map. Thus yielding a fluent imperative-like API that utilises the Map Lookup Operator to appear more familiar
                    to imperative programmers:
                    <figure>
                        <title>Example of Tasks using fluent imperative-like syntax</title>
                        <programlisting language="xquery">
task:value("hello")
    ? fmap(upper-case#1)
    ? fmap(concat(?, " adam"))
    ? RUN-UNSAFE()
                        </programlisting>
                    </figure>
                </para>
                <para>So our Task type is finalised as: <programlisting language="xquery">
map(xs:string, function(*))
                    </programlisting> More specifically our Task Map is defined as: <programlisting language="xquery">
map {
    'apply': as function(element(adt:realworld)) as item()+,
    'bind': as function($binder as function(item()*) as map(xs:string, function(*))) as map(xs:string, function(*)),
    'then': as function($next as map(xs:string, function(*))) as map(xs:string, function(*)),
    'fmap': as function($mapper as function(item()*) as item()*) as map(xs:string, function(*)),
    'sequence': as function($tasks as map(xs:string, function(*))+) as map(xs:string, function(*)),
    'async': as function() as map(xs:string, function(*)),
    'catch': as function($catch as function(xs:QName?, xs:string, map(*)) as map(xs:string, function(*))) as map(xs:string, function(*)),
    'catches': as function($codes as xs:QName*, $handler as function(xs:QName?, xs:string, map(xs:QName, item()*)?) as item()*) as map(xs:string, function(*)),
    'catches-recover': as function($codes as xs:QName*, $handler as function() as item()*) as map(xs:string, function(*)),
    'RUN-UNSAFE': as function() as item()*
}
                    </programlisting>
                    Observe that the <function>apply</function> entry inside the Task map retains our original Task type. The Map provides us with encapsulation
                    which allows for the creation of an imperative-like API. By refactoring our existing Task functions we have been able to preserve
                    both the function syntax-like API and the fluent imperative-like API. This provides developers the opportunity to choose whichever best suits their needs,
                    or to work with a mix of syntaxes as appropriate to them.
                </para>
            </sect3>
            
            <sect3>
                <title>Asynchronous Tasks</title>
                <para>
                    We provide a mechanism which explicitly allows the developer to state that a Task could benefit from being executed asynchronously. The <function>task:async</function> function
                    allows the developer to state their intention, however EXPath Tasks does not specify whether, how, or if this actually executes asynchronously. This gives
                    processors the ability to make informed decisions about concurrent execution based on input from the developer, but great freedom in how that is
                    actually executed. The only constraint on implemetations is that the order of execution within a task chain must be preserved.
                    Developers should rather think of <function>task:async</function> as providing a hint to the processor that asynchronous execution would be beneficial,
                    rather than assuming asynchronous execution will always take place. 
                </para>
                <para>Conversely, as the only constraint that we place on implementers is that the order of execution within a task chain must be preserved, compliant processors are
                    free to implicitly parallelise operations at execution time providing that constraint holds.</para>
            </sect3>
            
            <sect3>
                <title>Executing a Task</title>
                <para>Recall that a Haskell application starts with a <function>main</function> that must return an IO, thus framing the entire application as an IO action.
                    The result of executing an XPDL is always an instance of the <acronym linkend="acr_XDM">XDM</acronym> (and possibly a <acronym linkend="acr_PUL">PUL</acronym>).
                    Whilst we could certainly return a Task (map) as the result of the evaluation of our XPDL, what should the processor do when it encounters it? If the processor
                    decides to serialize the XDM then we are likely at the mercy of the W3C XSLT and XQuery Serialization specification, which certainly won't execute our Task by
                    <emphasis>applying</emphasis> it to transform the state of the world.
                </para>
                <para>Three potential solutions that present themselves from our research are:
                    <itemizedlist>
                        <listitem>
                            <para>Prescribe in the specification of EXPath Tasks that an implementation must execute a Task which is returned as the result of the
                                XPDL in a certain manner.</para>
                        </listitem>
                        <listitem>
                            <para>Incorporate the concept of a <acronym linkend="acr_PUL">PUL</acronym> into the specification of EXPath Tasks. Each Task would create 
                                an Update Primitive which is added into the PUL. The result of evaluating the XPDL would then be both an XDM and a PUL.</para>
                        </listitem>
                        <listitem>
                            <para>Provide an explicitly unsafe function for evaluating a Task, similar to Haskell's <code>unsafePerformIO</code>
                                or Monix Tasks's <function>runUnsafeSync</function>.</para>
                        </listitem>
                    </itemizedlist>
                </para>
                <para>We decided to adopt a hybrid approach. We provide a <function>task:RUN-UNSAFE</function> function, where we explicitly prescribe
                    that this should only appear <emphasis>once</emphasis> within an XPDL program, and that it <emphasis>must</emphasis> occur at the edge of the program,
                    i.e. as the main function. However, we also explicitly state that implementers are free to override this function. For example, implementations that already
                    support an XQuery Update <acronym>PUL</acronym>, may choose to promote a Task chain to a set of Update Primitives when this function is evaluated.</para>
            </sect3>

        </sect2>
            
        <sect2>
            <title>Using EXPath Tasks</title>
            <para>We provide several examples to demonstrate key features of EXPath Tasks.</para>
            
            <sect3>
                <title>Composing Tasks</title>
                <para>We can use monadic composition to safely compose together several
                    tasks that may at execution time cause side effects, but at evaluation
                    time result in an ordered chain of tasks.</para>
                <para>
                <example xml:id="exam_uppercasing">
                    <title>Safely Uppercasing a file</title>
                    <programlisting language="xquery">
task:value("/tmp/my-file")
    ?fmap(file:read-text#1)
    ?fmap(fn:upper-case#1)
    ?fmap(fn:write-text("/tmp/my-file-upper", ?))
                    </programlisting>
                </example>
                    Consider the code in <xref linkend="exam_uppercasing"/>. We use the EXPath File Module to read the text of a file, we then upper-case the text, and finally write the text
                    out to a new file. We start with a pure value Task holding the path of the source file, by <emphasis>mapping</emphasis> this through the <function>read-text</function>
                    function a second new task is created. At evaluation time nothing has been executed, instead we have a task that describes that first there is a file path, and then
                    secondly we should read a file from that path. We have composed two operations into one operation which preserves the ordering of the original operations. We then
                    continue by <emphasis>mapping</emphasis> through the <function>upper-case</function>, which composes another new task representing all three operations
                    (file path, read-text, and upper-case) in order. Our last mapping composition results in a final new task which represents all four operations in order. When
                    this final task is executed at runtime, each of the four operations will be performed in the correct order. 
                </para>
                <para>Through using the EXPath Tasks module, we have safely contained the side effects of the functions from the EXPath File Module,
                    by deferring them from evaluation time to execution time. As the Task is a state transformation, we have also threaded the <emphasis>World</emphasis>
                    through our task chain, which ensures that any XPDL processor must execute them in the correct order even in the face of aggressive optimisation.</para> 
            </sect3>

<!-- TODO we might consider adding a couple more examples -->
                
            <sect3>
                <title>Using Asynchronous Tasks</title>
                <para>We can lift a Task to an Asynchronous Task, which can help provide the XPDL
                    processor with hints about how best to parallelise an XPDL application.</para>
                <para>The following is a refactored version of the <emphasis>fork-join</emphasis> example from
                    xq-promise <biblioref linkend="bib_wright16"/>, to show how concurrent programming can
                    be structured safely using EXPath Tasks.</para>
                <para>The example performs 25 HTTP requests to 5 distinct servers and returns the results. First we show the synchronous version:
                    <example>
                        <title>Synchronous HTTP Fetching</title>
                        <programlisting language="xquery">
let $tasks := 
    for $uri in ((1 to 5) !  ('http://www.google.com', 'http://www.yahoo.com', 'http://www.amazon.com', 'http://cnn.com', 'http://www.msnbc.com'))
    let $task :=
        task:value($uri)
            ?fmap(http:send-request(&lt;http:request method="GET" /&gt;, ?))
            ?fmap(fn:tail#1)
            ?fmap(fn:trace(?, 'Results found: '))
            ?fmap(function ($res) {
                $res//*:a[@href =&gt; matches('^http')]
            })
return
    task:sequence($tasks)
        ?RUN-UNSAFE() 
                        </programlisting>
                    </example>
                    Now we show the asynchronous version, where we have only needed to insert two lines of code, the call to <function>task:async</function> which lifts
                    each Task into an Asynchronous Task, and a binding to <function>task:wait-all</function>:
                    <example>
                        <title>Asynchronous HTTP Fetching</title>
                        <programlisting language="xquery">
let $tasks :=
    for $uri in ((1 to 5) !  ('http://www.google.com', 'http://www.yahoo.com', 'http://www.amazon.com', 'http://cnn.com', 'http://www.msnbc.com'))
    let $task :=
        task:value($uri)
            ?fmap(http:send-request(&lt;http:request method="GET" /&gt;, ?))
            ?fmap(fn:tail#1)
            ?fmap(fn:trace(?, 'Results found: '))
            ?fmap(function ($res) {
                $res//*:a[@href =&gt; matches('^http')]
            })
            ?async()
return
    task:sequence($tasks)
        ?bind(task:wait-all#1)
        ?RUN-UNSAFE() 
                        </programlisting>
                    </example>
                </para>
            </sect3>
            
<!-- TODO DEBBIE - it would be nice to have examples in XSLT... alongside the XQuery ones -->

        </sect2>

    </sect1>
    
    <sect1>
        <title>Conclusion</title>
        <para>In this paper we have surveyed the current state-of-the-art mechanisms by which XPDL processors allow
            side effects and concurrent programming, and the options available to non-XPDLs for managing side effects
            and providing concurrent or parallel programming. From this research we have then developed and specified
            EXPath Tasks, a module of XPath extension functions, that allow developers to safely encapsulate
            side-effecting functions so that at evaluation time they appear as pure functions and enforce the expected
            order of execution. Finally, we have developed several reference implementations of EXPath Tasks to
            demonstrate the feasability of implementing our specification.</para>
        
        <para>Were the necessary functions available for performing node updates, we believe that the IO Monad approach
            taken by EXPath Tasks could even have benefits over using XQuery Update. Whilst it provides similarly strong
            deferred semantics like a <acronym>PUL</acronym>, a <emphasis>PUL</emphasis> is completely opaque, and one
            cannot compute over it, unlike a Task chain where Tasks may be composed together.</para>
        
        <para>Whilst at a casual glance it may appear that EXPath Tasks have some similarities to xq-promise, we should be careful to point out that they work
            quite differently in practice. We believe that EXPath Tasks has the following advantages over xq-promise:
            <itemizedlist>
                <listitem>
                    <para>Correct Ordering of Execution.</para>
                    <para>Under aggressive functional optimisation, EXPath Tasks will still preserve the correct order
                        of execution even when tasks have no explicit dependency between them. EXPath Tasks can
                        guarantee the order because they transparently thread the <emphasis>World</emphasis> through the
                        chain of computation as tasks are composed, which implicitly introduces dependencies between
                        the Tasks.</para>
                </listitem>
                <listitem>
                    <para>Flexible Asynchronous Processing.</para>
                    <para>The asynchronous processing model of EXPath Tasks is very generalised, and only makes
                        guarantees about ordering of execution. This enables many forms of concurrent programming to be
                        expressed using EXPath Tasks, whereas xq-promise only offers <emphasis>fork-join</emphasis>. In
                        fact xq-promise can easily be reimplemented atop EXPath tasks, including
                            <emphasis>fork-join</emphasis>: <programlisting>
declare function local:fork-join($tasks as task:Task(~An)+) as task:Task(array(~An)) {
    task:sequence($tasks ! task:async#1)
        ?bind(task:wait-all#1)
};
                        </programlisting>Interestingly, if the xq-promise API were reimplemented atop EXPath Tasks,
                        it would gain stronger guarantees about execution order. </para>
                    <para>Likewise our generalised approach, whilst making explicit the intention of parallelism, does not
                        restrict processors from making further implicit parallelisation optimisations.</para>
                </listitem>
                <listitem>
                    <para>Potential Performance</para>
                    <para>An xq-promise Promise is a deferred computation that cannot be executed until its
                            <function>fork-join</function> function is called. In comparison EXPath Tasks's Asynchronous
                        Tasks can begin execution at runtime as soon as their construct function is executed, thus
                        making better use of computer resources by starting computation earlier than would be possible
                        in xq-promise.</para>
                </listitem>
            </itemizedlist>
        </para>
        
        <para>It will certainly be interesting to see how the XML community responds to our EXPath Tasks
            specification. We are hopeful that developers working with Tasks need not necessarily have any
            understanding of Monads to be able to fully exploit the benefits of EXPath Tasks.</para>
        
        <para>We are still at an early stage of investigating how well use of the Task module can be incorporated into
            IXSL stylesheets for Saxon-JS applications. Does the Task module provide a good solution for handling
            asynchronous processing and side effects in Saxon-JS? This may only be answerable once more examples have
            been trialled, once the Saxon-JS implementation is more advanced.</para>
        
        <para>Given an existing Saxon-JS application, a move to use the Task module could involve a significant amount
            of restructuring. To use the Task module properly, all side-effecting expressions should be wrapped in
            tasks, and care would need to be taken to chain them together appropriately. Side-effecting expressions are
            likely to be found in numerous different templates; and so bringing the tasks together could be a challenge.
            It is unclear whether there would be a way to do this avoiding significant redesign.</para>
        
        <para>We have already found that the redesign of some mechanisms for handling interactive actions, to use
            aysnchronous tasks rather than <code>ixsl:schedule-action</code>, is not straight forward. For example,
            providing a mechanism which allows a user to abort an asynchronous HTTP request. Combining the use of Tasks
            with IXSL event handling templates, does not seem to work. Instead it seems a solution requires another way
            to create event listeners for nodes from within the XSLT. So, more work is required here. But it is
            certainly worth pursuing.</para>
        
        <sect2>
            <title>Future Work</title>
            <para>We have identified several areas for possible future research:
                <itemizedlist>
                    <listitem>
                        <para>Stronger/Stricter Explicit Typing</para>
                        <para>The explicit types we have specified in our Task Module are not as strict as we would
                            like. This is in general due to a lack of a stronger type system which would allow us to
                            express both abstract and generic types. At run-time the correct types will be inferred by
                            the processor. It would be interesting to research modifications to the XDM so that we can
                            statically express stricter types. For instance, the Saxon processor provides the tuple type
                                <biblioref linkend="bib_saxon_tuple-types"/> syntax extension as a way of defining a
                            more precise type for maps.</para>
                        <para>We recognise there may also be an approach where function generation is used, to generate Task functions with stricter types by type
                            switching on incoming parameters. Due to the large number of types in the XDM to switch over, such generation would itself likely need to be computed.</para>
                    </listitem>
                    <listitem>
                        <para>Side effects between Concurrent Tasks</para>
                        <para>We have provided no mechanisms for avoiding side effects across shared state between
                            parallel tasks at execution time, e.g. race conditions, data corruption, etc. Often such
                            issues can be avoided by developers decomposing asynchronous tasks into smaller asynchronous
                            tasks which have to synchronize via <function>task:wait-all</function>, and then begin
                            asynchronously again. A set of functional Task based synchronization primitives which could
                            be used to help in parallel situations would be an interesting extension. </para>
                    </listitem>
                    <listitem>
                        <para>Additional convenience functions</para>
                        <para>Whilst we have provided the building blocks necessary for general computation, additional
                            convenience functions could be added. For instance <function>gather</function> (similar to
                                <function>task:sequence</function> but with relaxed ordering),
                                <function>withAsync</function> (which lifts a normal function into an Asynchronous
                            Task), and <function>parZip</function> (which asynchronously zips the results of two tasks
                            together).</para>
                        <para>We have provided mechanisms for working with XPath errors, however we could also consider
                            functions for working with <emphasis>error values</emphasis>. We see no reason why something
                            akin to an Either (disjoint union) could not be developed to work with EXPath Tasks, where a
                            result is <emphasis>either</emphasis> an error value or the result of successful
                            computation.</para>
                    </listitem>
                </itemizedlist>
            </para>

<!-- TODO create non-encapsulated function versions in task.xq - gives the use then two alternative DSL syntaxes to use the API... or they could combine both as they like!?! -->

        </sect2>
    </sect1>
    
    <appendix xml:id="apdx_tasks-module">
        <title>EXPath Tasks Module Definitions</title>
        <sect1>
            <title>Namespaces and Prefixes</title>
            <para>This module makes use of the following namespaces to contain its application. The URIs of the namespaces and the conventional prefixes associated with them are:
                <itemizedlist>
                    <listitem>
                        <para>
                            <uri>http://expath.org/ns/task</uri> for functions -- associated with <code>task</code>.</para>
                    </listitem>
                    
                    <listitem>
                        <para>
                            <uri>http://expath.org/ns/task/adt</uri> for abstract data types -- associated with <code>adt</code>.</para>
                    </listitem>
                    
                </itemizedlist>
            </para>
        </sect1>
        <sect1>
            <title>Types</title>
            <para>As an attempt at simplifying the written definition of the functions within the Task Module, we have specified a number of type
                aliases. The concrete types are likely of little interest to users of the Task Module who are more concerned with behaviour
                than implementation detail. Implementers which need such detail may substitute the aliases for the concrete types
                as defined below.
            </para>
            <para>We have followed the XPath convention of using lower-cased names for our functions, apart from <function>task:RUN-UNSAFE</function>
                where the use of continuous capital letters is intended to draw developer attention. Our type aliases are described using a 
                capitalised-cased naming convention to visually distinguish them from function names.
            </para>
            <informaltable>
                <tgroup cols="2">
                    <thead>
                        <row>
                            <entry>Alias</entry>
                            <entry>Concrete Type</entry>
                        </row>
                    </thead>
                    <tbody>
                        <row>
                            <entry>
                                <emphasis>~A</emphasis>
                            </entry>
                            <entry>
                                <para>The <code>~</code> signifies that this is a generic type, and the <code>A</code> is just a placeholder for the actual
                            type. Concretely this is at least an <code>item()*</code>, however intelligent processors can likely infer and enforce stricter types
                            through the functionally composed Task chain.</para>
                            </entry>
                        </row>
                        <row>
                            <entry>
                                <emphasis>task:Task(~A)</emphasis>
                            </entry>
                            <entry>
                                <para>The <code>task:Task</code> type alias, is concretely <code>map(xs:string, function(*))</code>.</para>
                                <para>The inner aliased generic type, indicates that the Task when executed returns a result of type <code>~A</code>.</para>
                                <para>Specifically the Task map has the following non-optional entries:<programlisting language="xquery">
map {
    'apply': as function(World) as item()+,
    'bind': as function($binder $binder as function(~A) as task:Task(~B)) as task:Task(~B),
    'then': as function($next as task:Task(~B)) as task:Task(~B),
    'fmap': as function($mapper as function(~A) as ~B) as task:Task(~B),
    'sequence': as function($tasks as task:Task(~An)+) as task:Task(array(~An)),
    'async': as function() as task:Task(task:Async(~A)),
    'catch': as function($catch as function(xs:QName?, xs:string, map(*)) as task:Task(~B)) as task:Task(~B),
    'catches': as function($codes as xs:QName*, $handler as function(xs:QName?, xs:string, map(xs:QName, item()*)?) as ~B) as task:Task(~B),
    'catches-recover': as function($codes as xs:QName*, $handler as function() as ~B) as task:Task(~B),
    'RUN-UNSAFE': as function() as ~A
}
                                    </programlisting>
                                    <emphasis role="bold">Note:</emphasis> Each of the functions defined in the Task Map have the exact same behaviour as their cousins of the same name residing outside
                                    of the map. The only difference is that the functions inside the Map don't need an explicit task argument.
                                </para>
                            </entry>
                            
                        </row>
                        <row>
                            <entry>
                                <emphasis>task:ErrorObject</emphasis>
                            </entry>
                            <entry>
                                <para>The <code>task:ErrorObject</code> type alias, is concretely <code>map(xs:QName, item()*)</code>.</para>
                                <para>All entries in the map are optional, but otherwise it is structured as: <programlisting language="xquery">
map {
    xs:QName("err:value") : item()*,
    xs:QName("err:module") : xs:string?,
    xs:QName("err:line-number") : xs:integer?,
    xs:QName("err:column-number") : xs:integer?
    xs:QName("err:additional") : item()*
}
                                    </programlisting>
                                </para>
                            </entry>
                        </row>
                        <row>
                            <entry>
                                <emphasis>task:Async(~A)</emphasis>
                            </entry>
                            <entry>
                                <para>The <code>task:Async</code> type alias, is concretely <code>function(element(adt:scheduler)) as ~A</code>.</para>
                                <para>The inner aliased generic type, indicates that the Async if it runs to completion will compute a result of type <code>~A</code>.</para>
                            </entry>
                        </row>
                    </tbody>
                </tgroup>
            </informaltable>
        </sect1>
        <sect1>
            <title>Functions</title>
            <sect2>
                <title>Basic Task Construction</title>
                <para>This group of functions offer facilities for constructing basic tasks. They usually form the starting point of a task chain.</para>
                <sect3>
                    <title>task:value</title>
                    <variablelist>
                        <varlistentry>
                            <term>Summary</term>
                            <listitem>
                                <para>Constructs a Task from a <emphasis>pure</emphasis> value.</para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Signature</term>
                            <listitem>
                                <para>
                                    <code>
                                        <function>task:value</function>(<varname>$v</varname> as <type>~A</type>) as <returnvalue>task:Task(~A)</returnvalue>
                                    </code>.</para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Rules</term>
                            <listitem>
                                <para>When the task is run it will return the value of <varname>$v</varname>.</para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Notes</term>
                            <listitem>
                                <para>In Haskell this would be known as <code>return</code> or sometimes alternatively <code>unit</code>.</para>
                                <para>In Scala Monix this would be known as <function>now</function> or <function>pure</function>.</para>
                                <para>In formal descriptive terms this is:
                                    <programlisting language="haskell">
<function>value</function> :: <parameter>a</parameter> -&gt; <returnvalue>Task a</returnvalue>
                                    </programlisting>
                                </para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Example</term>
                            <listitem>
                                <example>
                                    <title>Task from a String</title>
                                    <programlisting language="xquery">
task:value("hello world")
                                    </programlisting>
                                </example>
                            </listitem>
                        </varlistentry>
                    </variablelist>
                </sect3>
                <sect3>
                    <title>task:of</title>
                    <variablelist>
                        <varlistentry>
                            <term>Summary</term>
                            <listitem>
                                <para>Constructs a Task from a function.</para>
                                <para>This provides a way to wrap a potentially non-pure (i.e. side-effecting) function and delay its execution until the Task is executed.</para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Signature</term>
                            <listitem>
                                <para>
                                    <code>
                                        <function>task:of</function>(<varname>$f</varname> as <type>function()</type> as <type>~A</type>) as <returnvalue>task:Task(~A)</returnvalue>
                                    </code>.</para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Rules</term>
                            <listitem>
                                <para>The function is lifted into the task, which is to say that the function will not be executed until the task is executed.
                                    When the task is run, it will execute the function and return its result.</para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Notes</term>
                            <listitem>
                                <para>In Haskell there is no direct equivalent.</para>
                                <para>In Scala Monix this would be known as <function>eval</function> or <function>delay</function>.</para>
                                <para>In formal descriptive terms this is:
                                    <programlisting language="haskell">
<function>of</function> :: <parameter>(() -&gt; a)</parameter> -&gt; <returnvalue>Task a</returnvalue>
                                    </programlisting>
                                </para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Example</term>
                            <listitem>
                                <example>
                                    <title>Task which computes the system time from a side-effecting function.</title>
                                    <programlisting language="xquery">
task:of(util:system-time#0)
                                    </programlisting>
                                </example>
                            </listitem>
                        </varlistentry>
                    </variablelist>
                </sect3>
            </sect2>
            <sect2>
                <title>Task Composition</title>
                <para>This group of functions offer facilities for functionally composing tasks together.</para>
                <sect3>
                    <title>task:bind</title>
                    <variablelist>
                        <varlistentry>
                            <term>Summary</term>
                            <listitem>
                                <para>Composes a new Task from an existing task and a binder function which creates a new task from the existing task's value.</para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Signature</term>
                            <listitem>
                                <para>
                                    <code>
                                        <function>task:bind</function>(<varname>$task</varname> as <type>task:Task(~A)</type>, <varname>$binder</varname> as <type>function(~A)</type> as <type>task:Task(~B)</type>) as <returnvalue>task:Task(~B)</returnvalue>
                                    </code>.</para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Rules</term>
                            <listitem>
                                <para>When the resultant task is executed, the binder function processes the existing task's value, and then
                                    the result of the task is returned.</para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Notes</term>
                            <listitem>
                                <para>In Haskell this is also called <code>bind</code> and often written as <code>&gt;&gt;=</code>.</para>
                                <para>In Scala Monix this is known as <function>flatMap</function>.</para>
                                <para>In formal descriptive terms this is:
                                    <programlisting language="haskell">
<function>bind</function> :: <parameter>Task a -&gt; (a -&gt; Task b)</parameter> -&gt; <returnvalue>Task b</returnvalue>
                                    </programlisting>
                                </para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Examples</term>
                            <listitem>
                                <example>
                                    <title>Using bind to Square a number</title>
                                    <programlisting language="xquery">
task:bind(task:value(99), function($v) {
    task:value($v * $v)
})
                                    </programlisting>
                                </example>
                                <example>
                                    <title>Using bind to Transform a value</title>
                                    <programlisting language="xquery">
task:bind(task:value("hello"), function($v) {
    task:value(fn:upper-case($v))
})
                                    </programlisting>
                                </example>
                                <example>
                                    <title>Using bind to conditionally raise an error</title>
                                    <programlisting language="xquery">
task:bind(task:value("hello"), function($v) {
    if ($v eq "goodbye")
    then
        task:error((), "It's not yet time to say goodbye!", ())
    else
        task:value($v)
})
                                    </programlisting>
                                </example>
                                <example>
                                    <title>Using bind to compose two tasks</title>
                                    <programlisting language="xquery">
let $task1 := task:value("hello")
let $task2 := task:value("world")
return
    task:bind($task1, function($v1) {
        task:bind($task2, function($v2) {
            task:value($v1 || " " || $v2)
        })
    })
                                    </programlisting>
                                </example>
                            </listitem>
                        </varlistentry>
                    </variablelist>
                </sect3>
                <sect3>
                    <title>task:then</title>
                    <variablelist>
                        <varlistentry>
                            <term>Summary</term>
                            <listitem>
                                <para>Composes a new Task from an existing task and a new task. It is similar to <function>task:bind</function> but discards the existing task's value.</para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Signature</term>
                            <listitem>
                                <para>
                                    <code>
                                        <function>task:then</function>(<varname>$task</varname> as <type>task:Task(~A)</type>, <varname>$next</varname> as <type>task:Task(~B)</type>) as <returnvalue>task:Task(~B)</returnvalue>
                                    </code>.</para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Rules</term>
                            <listitem>
                                <para>When the resultant task is executed, the existing task is executed and the result discarded, and then
                                    the result of the next task is returned.</para>
                                <para>
                                    <code>task:then($task, $next)</code> is equivalent to <code>task:bind($task, function($_) { $next })</code>.</para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Notes</term>
                            <listitem>
                                <para>In Haskell this is also a form of bind which is sometimes called <code>then</code>, and often written as <code>&gt;&gt;</code>.</para>
                                <para>In Scala Monix this is direct equivalent.</para>
                                <para>In formal descriptive terms this is:
                                    <programlisting language="haskell">
<function>then</function> :: <parameter>Task a -&gt; (_ -&gt; Task b)</parameter> -&gt; <returnvalue>Task b</returnvalue>
                                    </programlisting>
                                </para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Example</term>
                            <listitem>
                                <example>
                                    <title>Sequentially composing two tasks</title>
                                    <programlisting language="xquery">
task:then(task:value("something we don't further need"), task:value("something important"))
                                    </programlisting>
                                </example>
                            </listitem>
                        </varlistentry>
                    </variablelist>
                </sect3>
                <sect3>
                    <title>task:fmap</title>
                    <variablelist>
                        <varlistentry>
                            <term>Summary</term>
                            <listitem>
                                <para>Composes a new Task from an existing task and a mapping function which creates a new value from the existing task's value.</para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Signature</term>
                            <listitem>
                                <para>
                                    <code>
                                        <function>task:fmap</function>(<varname>$task</varname> as <type>task:Task(~A)</type>, <varname>$mapper</varname> as <type>function(~A)</type> as <type>~B</type>) as <returnvalue>task:Task(~B)</returnvalue>
                                    </code>.</para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Rules</term>
                            <listitem>
                                <para>When the resultant task is executed, the mapper function processes the existing task's value, and then
                                    the result of the task is returned.</para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Notes</term>
                            <listitem>
                                <para>In Haskell this is also called <code>fmap</code> and often written as <code>&lt;$&gt;</code>.</para>
                                <para>In Scala Monix this is known as <function>map</function>.</para>
                                <para>In formal descriptive terms this is:
                                    <programlisting language="haskell">
<function>fmap</function> :: <parameter>Task a -&gt; (a -&gt; b)</parameter> -&gt; <returnvalue>Task b</returnvalue>
                                    </programlisting>
                                </para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Examples</term>
                            <listitem>
                                <example>
                                    <title>Upper-casing a Task String</title>
                                    <programlisting language="xquery">
task:fmap(task:value("hello"), fn:upper-case#1)
                                    </programlisting>
                                </example>
                                <example>
                                    <title>Concatenating a Task String</title>
                                    <programlisting language="xquery">
task:fmap(task:value("hello"), fn:concat(?, " world"))
                                    </programlisting>
                                </example>
                                <example>
                                    <title>Extracting the code-points of a Task String (e.g. type conversion, String to Integer+)</title>
                                    <programlisting language="xquery">
task:fmap(task:value("hello"), fn:string-to-codepoints#1)
                                    </programlisting>
                                </example>
                            </listitem>
                        </varlistentry>
                    </variablelist>
                </sect3>
                <sect3>
                    <title>task:sequence</title>
                    <variablelist>
                        <varlistentry>
                            <term>Summary</term>
                            <listitem>
                                <para>Constructs a new Task representating the sequential
                                    application of one or more other tasks.</para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Signature</term>
                            <listitem>
                                <para>
                                    <code>
                                        <function>task:sequence</function>(<varname>$tasks</varname> as <type>task:Task(~An)+</type>) as <returnvalue>task:Task(array(~An))</returnvalue>
                                    </code>.</para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Rules</term>
                            <listitem>
                                <para>When the resultant task is executed, each of the provided tasks will be executed sequentially, and the results returned as an XDM array. The order
                                    of entries in the resultant array is the same as the order of <varname>$tasks</varname>.</para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Notes</term>
                            <listitem>
                                <para>In Haskell and Scala Monix this is known as <code>sequence</code>.</para>
                                <para>In formal descriptive terms this is:
                                    <programlisting language="haskell">
<function>sequence</function> :: <parameter>[Task a]</parameter> -&gt; <returnvalue>Task [a]</returnvalue>
                                    </programlisting>
                                </para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Examples</term>
                            <listitem>
                                <example>
                                    <title>Sequencing three Tasks into one</title>
                                    <programlisting language="xquery">
task:sequence((task:value("hello"), task:value(54), task:value("goodbye"))
                                    </programlisting>
                                </example>
                            </listitem>
                        </varlistentry>
                    </variablelist>
                </sect3>
            </sect2>
            <sect2>
                <title>Task Error Management</title>
                <para>This group of functions offers facilities for using tasks in the face of XPath errors. Several can be used along with <function>task:error</function>
                    as a form of conditional branching or downward flow control.</para>
                <sect3>
                    <title>task:error</title>
                    <variablelist>
                        <varlistentry>
                            <term>Summary</term>
                            <listitem>
                                <para>Constructs a Task that raises an error.</para>
                                <para>This is a Task abstraction for <function>fn:error</function>.</para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Signature</term>
                            <listitem>
                                <para>
                                    <code>
                                        <function>task:error</function>(<varname>$code</varname> as <type>xs:QName?</type>, <varname>$description</varname> as <type>xs:string</type>, <varname>$error-object</varname> as <type>task:ErrorObject?</type>) as <returnvalue>task:Task(none)</returnvalue>
                                    </code>.</para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Rules</term>
                            <listitem>
                                <para>The error is not raised until the task is run.</para>
                                <para>The parameters <varname>$code</varname>, and <varname>$description</varname> have the same purpose as those with the same name defined for <function>fn:error</function>.</para>
                                <para>The parameter <varname>$error-object</varname> has the same purpose but is a type restriction of the parameter with the same name defined for <function>fn:error</function>, it should
                                    be of type <type>task:ErrorObject</type>.</para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Notes</term>
                            <listitem>
                                <para>In Haskell this would be closest to <code>fail</code>.</para>
                                <para>In Scala Monix this would be known as <function>raiseError</function>.</para>
                                <para>In formal descriptive terms this is:
                                    <programlisting language="haskell">
<function>error</function> :: <parameter>(code, description, error-object)</parameter> -&gt; <returnvalue>Task none</returnvalue>
                                    </programlisting>
                                </para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Examples</term>
                            <listitem>
                                <example>
                                    <title>Constructing a simple Task Error</title>
                                    <programlisting language="xquery">
task:error(xs:QName("local:error001"), "BOOM!", ())
                                    </programlisting>
                                </example>
                            </listitem>
                        </varlistentry>
                    </variablelist>
                </sect3>
                <sect3>
                    <title>task:catch</title>
                    <variablelist>
                        <varlistentry>
                            <term>Summary</term>
                            <listitem>
                                <para>Constructs a Task which catches any error raised by another task.</para>
                                <para>This is similar to <function>task:catches</function> except that all errors are caught.</para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Signature</term>
                            <listitem>
                                <para>
                                    <code>
                                        <function>task:catch</function>(<varname>$task</varname> as <type>task:Task(~A)</type>, <varname>$handler</varname> as <type>function(xs:QName?, xs:string, task:ErrorObject?)</type> as <type>task:Task(~B)</type>) as <returnvalue>task:Task(~B)</returnvalue>
                                    </code>.</para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Rules</term>
                            <listitem>
                                <para>When the resultant task is executed, the handler function catches any error from executing the existing task, and then
                                    the result of the handler task is returned.</para>
                                <para>The handler function accepts three arguments, the first is the QName of the error that was caught, the second is
                                    the description of the error that was caught, and the third are the ancillary error details collected as a <code>task:ErrorObject</code>.</para>
                                <para>If no errors are raised by the existing task, the handler will not be called, and instead this task acts as an identity function.</para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Notes</term>
                            <listitem>
                                <para>In Haskell this is similar to <code>catch</code>.</para>
                                <para>In Scala Monix this would be similar to <function>onErrorHandleWith</function>.</para>
                                <para>In formal descriptive terms this is:
                                    <programlisting language="haskell">
<function>catches</function> :: <parameter>Task a -&gt; ([code, description, errorObject] -&gt; Task b)</parameter> -&gt; <returnvalue>Task b</returnvalue>
                                    </programlisting>
                                </para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Example</term>
                            <listitem>
                                <example>
                                    <title>Using catch to recover from an error</title>
                                    <programlisting language="xquery">
let $my-error-code := xs:QName("local:error01")
return
    task:catch(task:error($my-error-code, "Boom!", ()), function($actual-code, $actual-description, $actual-error-object) {
        "Handled error: " || $actual-code
    })
                                        </programlisting>
                                </example>
                            </listitem>
                        </varlistentry>
                    </variablelist>
                </sect3>
                <sect3>
                    <title>task:catches</title>
                    <variablelist>
                        <varlistentry>
                            <term>Summary</term>
                            <listitem>
                                <para>Constructs a Task which catches specific errors of another task.</para>
                                <para>This is similar to <function>task:catch-recover</function> except that the error handler receives details of the error.</para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Signature</term>
                            <listitem>
                                <para>
                                    <code>
                                        <function>task:catches</function>(<varname>$task</varname> as <type>task:Task(~A)</type>, <varname>$codes</varname> as <type>xs:QName*</type>, <varname>$handler</varname> as <type>function(xs:QName?, xs:string, task:ErrorObject?)</type> as <type>~B</type>) as <returnvalue>task:Task(~B)</returnvalue>
                                    </code>.</para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Rules</term>
                            <listitem>
                                <para>When the resultant task is executed, the handler function catches any matching errors identified by the parameter <parameter>$codes</parameter> from executing the existing task, and then
                                    the result of the handler task is returned.</para>
                                <para>The handler function accepts three arguments, the first is the QName of the error that was caught, the second is
                                    the description of the error that was caught, and the third are the ancillary error details collected as a <code>task:ErrorObject</code>.</para>
                                <para>If no errors are raised by the existing task, the handler will not be called, and instead this task acts as an identity function.</para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Notes</term>
                            <listitem>
                                <para>In Haskell this is similar to <code>catches</code>.</para>
                                <para>In Scala Monix this would be similar to <function>onErrorHandle</function>.</para>
                                <para>In formal descriptive terms this is:
                                    <programlisting language="haskell">
<function>catches</function> :: <parameter>Task a -&gt; ([code] -&gt; ([code, description, errorObject] -&gt; b))</parameter> -&gt; <returnvalue>Task b</returnvalue>
                                    </programlisting>
                                </para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Example</term>
                            <listitem>
                                <example>
                                    <title>Using catches to recover from an error</title>
                                    <programlisting language="xquery">
let $my-error-code := xs:QName("local:error01")
return
    task:catches(task:error($my-error-code, "Boom!", ()), ($my-error-code, xs:QName("err:XPDY004")), function($actual-code, $actual-description, $actual-error-object) {
        "Handled error: " || $actual-code
    })
                                        </programlisting>
                                </example>
                            </listitem>
                        </varlistentry>
                    </variablelist>
                </sect3>
                <sect3>
                    <title>task:catches-recover</title>
                    <variablelist>
                        <varlistentry>
                            <term>Summary</term>
                            <listitem>
                                <para>Constructs a Task which catches specific errors of another task.</para>
                                <para>This is similar to <function>task:catches</function> except that the error handler does not receive details of the error.</para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Signature</term>
                            <listitem>
                                <para>
                                    <code>
                                        <function>task:catches-recover</function>(<varname>$task</varname> as <type>task:Task(~A)</type>, <varname>$codes</varname> as <type>xs:QName*</type>, <varname>$handler</varname> as <type>function()</type> as <type>~B</type>) as <returnvalue>task:Task(~B)</returnvalue>
                                    </code>.</para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Rules</term>
                            <listitem>
                                <para>When the resultant task is executed, the handler function catches any matching errors identified by the parameter <parameter>$codes</parameter> from executing the existing task, and then
                                    the result of the handler task is returned.</para>
                                <para>If no errors are raised by the existing task, the handler will not be called, and instead this task acts as an identity function.</para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Notes</term>
                            <listitem>
                                <para>In Haskell this is similar to <code>catches</code>, but it does not pass the error details to the <parameter>$handler</parameter>.</para>
                                <para>In Scala Monix this would be similar to <function>onErrorRecover</function>.</para>
                                <para>In formal descriptive terms this is:
                                    <programlisting language="haskell">
<function>catches-recover</function> :: <parameter>Task a -&gt; ([code] -&gt; (\_ -&gt; b))</parameter> -&gt; <returnvalue>Task b</returnvalue>
                                    </programlisting>
                                </para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Example</term>
                            <listitem>
                                <example>
                                    <title>Using catches-recover to recover from an error</title>
                                    <programlisting language="xquery">
let $my-error-code := xs:QName("local:error01")
return
    task:catches-recover(task:error($my-error-code, "Boom!", ()), ($my-error-code), function() {
        "Recovering from error..."
    })
                                        </programlisting>
                                </example>
                            </listitem>
                        </varlistentry>
                    </variablelist>
                </sect3>
            </sect2>
            <sect2>
                <title>Asynchronous Tasks</title>
                <para>This group of functions offers facilities for constructing asynchronous tasks and acting upon their progress.</para>
                <sect3>
                    <title>task:async</title>
                    <variablelist>
                        <varlistentry>
                            <term>Summary</term>
                            <listitem>
                                <para>Constructs an Asynchronous Task from an existing Task.</para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Signature</term>
                            <listitem>
                                <para>
                                    <code>
                                        <function>task:async</function>(<varname>$task</varname> as <type>task:Task(~A)</type>) as <returnvalue>task:Task(task:Async(~A))</returnvalue>
                                    </code>.</para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Rules</term>
                            <listitem>
                                <para>The existing task will be composed into a new task which may be executed asynchronously.</para>
                                <para>This function makes no guarantees about how, when, or if the asynchronous task is executed
                                    other than the fact that execution will not begin before the task itself is executed.</para>
                                <para>Implementations are free to implement asynchronous tasks using any mechanism they
                                    wish including cooperative multitasking, preemptive multitasking, or even plain old
                                    single-threaded synchronous. The only restriction on implementations is that the processing order
                                    of task chains and asynchronous task chains must be preserved, so that the user gets the
                                    result that they should expect.</para>
                                <para>
                                    When the task is run, it may start an asynchronous process which executes the task, regardless it returns
                                    a reference to the (possibly) asynchronous process, which may later be used for cancellation or obtaining
                                    the result of the task.</para>
                                <para>If the function call results in asynchronous behaviour (i.e. a fork of the execution path happens),
                                    then the asynchronous task inherits the <emphasis>Static Context</emphasis>, and a copy of the <emphasis>Dynamic Context</emphasis>
                                    where the <emphasis>Context item</emphasis>, <emphasis>Context position</emphasis>, and <emphasis>Context size</emphasis> have been reinitialised.
                                    If an implementation supports XQuery Update <acronym linkend="bacr_PUL">PUL</acronym>, then any Update Primitives 
                                    generated in the Asynchronous Task are merged back to the main Task only when <function>task:wait</function>
                                    or <function>task:wait-all</function> is employed.</para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Notes</term>
                            <listitem>
                                <para>In Haskell this is similar to <code>async</code> from the <code>Control.Concurrent.Async</code> package.</para>
                                <para>In Scala Monix this would be known as <function>executeAsync</function>.</para>
                                <para>In formal descriptive terms this is:
                                    <programlisting language="haskell">
<function>async</function> :: <parameter>Task a</parameter> -&gt; <returnvalue>Task (Async a)</returnvalue>
                                    </programlisting>
                                </para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Example</term>
                            <listitem>
                                <example>
                                    <title>Task which asynchronously posts a document</title>
                                    <programlisting language="xquery">
task:async(
    task:fmap(
        task:value("http://somewebsite.com"),
        http:post(?, &lt;some-document/&gt;)
    )
)
                                    </programlisting>
                                </example>
                            </listitem>
                        </varlistentry>
                    </variablelist>
                </sect3>
                <sect3>
                    <title>task:wait</title>
                    <variablelist>
                        <varlistentry>
                            <term>Summary</term>
                            <listitem>
                                <para>Given an Async this function will extract its value and return a Task of the value.</para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Signature</term>
                            <listitem>
                                <para>
                                    <code>
                                        <function>task:wait</function>(<varname>$async</varname> as <type>task:Async(~A)</type>) as <returnvalue>task:Task(~A)</returnvalue>
                                    </code>.</para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Rules</term>
                            <listitem>
                                <para>At execution time of the task returned by this function, if the Asynchronous computation represented by the <parameter>$async</parameter> reference
                                    has not yet completed, then this function will block until the asynchronous computation completes.</para>
                                <para>This function makes no guarantees about how, when, or if blocking occurs other than the fact that
                                    any blocking (if required) will not begin before the task itself is executed.</para>
                                <para>Implementations are free to implement waiting upon asynchronous tasks using any mechanism they
                                    wish. The only restriction on implementations is that the processing order
                                    of task chains and asynchronous task chains must be preserved, so that the user gets the
                                    result that they should expect.</para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Notes</term>
                            <listitem>
                                <para>In Haskell this is similar to <code>wait</code> from the <code>Control.Concurrent.Async</code> package.</para>
                                <para>In Scala Monix this would be similar to <function>Await.result</function>.</para>
                                <para>In formal descriptive terms this is:
                                    <programlisting language="haskell">
<function>wait</function> :: <parameter>Async a</parameter> -&gt; <returnvalue>Task a</returnvalue>
                                    </programlisting>
                                </para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Example</term>
                            <listitem>
                                <example>
                                    <title>Task waiting on an asynchronous task</title>
                                    <programlisting language="xquery">

let $async-task :=
    task:async(
        task:fmap(
            task:value("http://somewebsite.com"),
            http:post(?, &lt;some-document/&gt;)
        )
    )
return

    (: some further task chain of processing... :)
    
    (: wait on the asynchronous task to complete :)
    task:bind(
        $async-task,
        task:wait#1
    )
                                    </programlisting>
                                </example>
                            </listitem>
                        </varlistentry>
                    </variablelist>
                </sect3>
                <sect3>
                    <title>task:wait-all</title>
                    <variablelist>
                        <varlistentry>
                            <term>Summary</term>
                            <listitem>
                                <para>Given multiple Asyncs this function will extract their values and return a Task of the values.</para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Signature</term>
                            <listitem>
                                <para>
                                    <code>
                                        <function>task:wait-all</function>(<varname>$asyncs</varname> as <type>array(task:Async(~A))</type>) as <returnvalue>task:Task(array(~A))</returnvalue>
                                    </code>.</para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Rules</term>
                            <listitem>
                                <para>At execution time of the task returned by this function, if any of the Asynchronous computations represented by the <parameter>$asyncs</parameter> references
                                    have not yet completed, then this function will block until all the asynchronous computations complete.</para>
                                <para>This function makes no guarantees about how, when, or if blocking occurs other than the fact that
                                    any blocking (if required) will not begin before the task itself is executed.</para>
                                <para>Implementations are free to implement waiting upon asynchronous tasks using any mechanism they
                                    wish. The only restriction on implementations is that the processing order
                                    of task chains and asynchronous task chains must be preserved, so that the user gets the
                                    result that they should expect.</para>
                                <para>This is equivalent to: <programlisting language="xquery">
task:bind($task, function($asyncs as array(*)) as map(xs:string, function(*)) {
    task:sequence(array:flatten(array:for-each($asyncs, task:wait#1)))
}) 
                                    </programlisting>
                                </para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Notes</term>
                            <listitem>
                                <para>In Haskell there is no direct equivalent, but it can be modelled by a combination of <code>wait</code> and <code>sequence</code>.</para>
                                <para>In Scala Monix there is no direct equivalent.</para>
                                <para>In formal descriptive terms this is:
                                    <programlisting language="haskell">
<function>wait-all</function> :: <parameter>[Async a]</parameter> -&gt; <returnvalue>Task [a]</returnvalue>
                                    </programlisting>
                                </para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Example</term>
                            <listitem>
                                <example>
                                    <title>Task waiting on multiple asynchronous tasks</title>
                                    <programlisting language="xquery">
let $async-tasks :=
    (
        task:async(
            task:fmap(
                task:value("http://websiteone.com"),
                http:post(?, &lt;some-document/&gt;)
            )
        ),
        task:async(
            task:fmap(
                task:value("http://websitetwo.com"),
                http:post(?, &lt;some-document/&gt;)
            )
        )
    )
return

    (: some further task chain of processing... :)
    
    (: wait for all asynchronous tasks to complete :)
    task:bind(
        task:sequence($async-tasks),
        task:wait-all#1
    )
                                    </programlisting>
                                </example>
                            </listitem>
                        </varlistentry>
                    </variablelist>
                </sect3>
                <sect3>
                    <title>task:cancel</title>
                    <variablelist>
                        <varlistentry>
                            <term>Summary</term>
                            <listitem>
                                <para>Given an Async this function will attempt to cancel the asynchronous process.</para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Signature</term>
                            <listitem>
                                <para>
                                    <code>
                                        <function>task:cancel</function>(<varname>$async</varname> as <type>task:Async(~A)</type>) as <returnvalue>task:Task()</returnvalue>
                                    </code>.</para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Properties</term>
                            <listitem>
                                <para>This function is <emphasis>non-blocking</emphasis>.</para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Rules</term>
                            <listitem>
                                <para>At execution time of the task returned by this function, cancellation of the Asynchronous computation
                                    represented by the <parameter>$async</parameter> reference
                                    may be attempted.</para>
                                <para>This function makes no guarantees about how, when, or if cancellation occurs other than the fact that
                                    any cancellation (if required/possible) will not begin before the task itself is executed.
                                    Regardless the Asynchronous reference is invalidated by this function.</para>
                                <para>Implementations are free to implement cancellation of asynchronous tasks using any mechanism they
                                    wish, they are also free to ignore cancellation as long as the Asynchronous reference is still invalidated.
                                    The only restriction on implementations is that the processing order
                                    of task chains and asynchronous task chains must be preserved, so that the user gets the
                                    result that they should expect.</para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Notes</term>
                            <listitem>
                                <para>In Haskell this is similar to <code>cancel</code> from the <code>Control.Concurrent.Async</code> package.</para>
                                <para>In Scala Monix this is known as `cancel`.</para>
                                <para>In formal descriptive terms this is:
                                    <programlisting language="haskell">
<function>cancel</function> :: <parameter>Async a</parameter> -&gt; <returnvalue>Task ()</returnvalue>
                                    </programlisting>
                                </para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Example</term>
                            <listitem>
                                <example>
                                    <title>Cancelling  an asynchronous task</title>
                                    <programlisting language="xquery">

let $async-task :=
    task:async(
        task:fmap(
            task:value("http://somewebsite.com"),
            http:post(?, &lt;some-document/&gt;)
        )
    )
return

    (: some further task chain of processing... :)
    
    (: cancel the asynchronous task :)
    task:bind(
        $async-task,
        task:cancel#1
    )
                                    </programlisting>
                                </example>
                            </listitem>
                        </varlistentry>
                    </variablelist>
                </sect3>
                <sect3>
                    <title>task:cancel-all</title>
                    <variablelist>
                        <varlistentry>
                            <term>Summary</term>
                            <listitem>
                                <para>Given multiple Asyncs this function will attempt to cancel all of the asynchronous processes.</para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Signature</term>
                            <listitem>
                                <para>
                                    <code>
                                        <function>task:cancel-all</function>(<varname>$asyncs</varname> as <type>array(task:Async(~A))</type>) as <returnvalue>task:Task()</returnvalue>
                                    </code>.</para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Properties</term>
                            <listitem>
                                <para>This function is <emphasis>non-blocking</emphasis>.</para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Rules</term>
                            <listitem>
                                <para>At execution time of the task returned by this function, cancellation of all Asynchronous computations
                                    represented by the <parameter>$asyncs</parameter> references
                                    may be attempted.</para>
                                <para>This function makes no guarantees about how, when, or if cancellation occurs other than the fact that
                                    any cancellation (if required/possible) will not begin before the task itself is executed.
                                    Regardless the Asynchronous references are invalidated by this function.</para>
                                <para>Implementations are free to implement cancellation of asynchronous tasks using any mechanism they
                                    wish, they are also free to ignore cancellation as long as the Asynchronous references are still invalidated.
                                    The only restriction on implementations is that the processing order
                                    of task chains and asynchronous task chains must be preserved, so that the user gets the
                                    result that they should expect.</para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Notes</term>
                            <listitem>
                                <para>In Haskell there is no direct equivalent, but it can be modelled by a combination of <code>cancel</code> and <code>sequence</code>.</para>
                                <para>In Scala Monix there is no direct equivalent.</para>
                                <para>In formal descriptive terms this is:
                                    <programlisting language="haskell">
<function>cancel-all</function> :: <parameter>[Async a]</parameter> -&gt; <returnvalue>Task ()</returnvalue>
                                    </programlisting>
                                </para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Example</term>
                            <listitem>
                                <example>
                                    <title>Cancelling asynchronous tasks</title>
                                    <programlisting language="xquery">
let $async-tasks :=
    (
        task:async(
            task:fmap(
                task:value("http://websiteone.com"),
                http:post(?, &lt;some-document/&gt;)
            )
        ),
        task:async(
            task:fmap(
                task:value("http://websitetwo.com"),
                http:post(?, &lt;some-document/&gt;)
            )
        )
    )
return

    (: some further task chain of processing... :)
    
    (: cancel all asynchronous tasks :)
    task:bind(
        task:sequence($async-tasks),
        task:cancel-all#1
    )
                                    </programlisting>
                                </example>
                            </listitem>
                        </varlistentry>
                    </variablelist>
                </sect3>
            </sect2>
            <sect2>
                <title>Unsafe Tasks</title>
                <para>This defines a single function <code>task:RUN-UNSAFE</code>, which is useful only when a task chain needs to be executed.
                    If an XPDL implementation cannot provide a better mechanism, then this may be implemented and used as a last resort.</para>
                <sect3>
                    <title>task:RUN-UNSAFE</title>
                    <variablelist>
                        <varlistentry>
                            <term>Summary</term>
                            <listitem>
                                <para>Executes a Task Chain and returns the result.</para>
                                <para>This function is <emphasis role="bold">inherently unsafe</emphasis>, as it causes any side effects within the Task chain to be actualised.</para>
                                <para>If this function is used within an application, it should only be invoked once, and it should be at the edge of the application, i.e. in the position
                                    where it is the first and only thing to be directly executed by the application at runtime. No further computation, neither on the result of
                                    this function, or after this function call should be attempted by the application.</para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Signature</term>
                            <listitem>
                                <para>
                                    <code>
                                        <function>task:RUN-UNSAFE</function>(<varname>$task</varname> as <type>task:Task(~A)</type>) as <returnvalue>~A</returnvalue>
                                    </code>.</para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Properties</term>
                            <listitem>
                                <para>This function is <emphasis>nondeterministic</emphasis>.</para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Rules</term>
                            <listitem>
                                <para>At execution time, the task chain is evaluated and the result returned.</para>
                                <para>However, if implementations can provide a safer mechanism for the execution
                                    of a Task after the XPDL has completed evaluation, then they are free to
                                    override this as they see fit. Once such mechanism could be to promote the Task chain
                                    to a set of Update Primitives within a PUL and then demote this to an identity function.
                                </para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Notes</term>
                            <listitem>
                                <para>In Haskell the closest equivalent is <code>unsafePerformIO</code>.</para>
                                <para>In Scala Monix the closest approach would be a combination of <function>runToFuture</function> and <function>Await.result</function>.</para>
                                <para>In formal descriptive terms this is:
                                    <programlisting language="haskell">
<function>RUN-UNSAFE</function> :: <parameter>Task a</parameter> -&gt; <returnvalue>a</returnvalue>
                                    </programlisting>
                                </para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Example</term>
                            <listitem>
                                <example>
                                    <title>Unsafely executing a Task</title>
                                    <programlisting language="xquery">
(:~
 : Just a utility function for calculating
 : previous sightings of Hayley's comet
 :)
declare function local:hayleys-sightings($before-year) {
    let $start := 1530
    let $interval := 76

    for $range in ($start - $interval to $before-year - $interval)
    let $visible := $range + $interval
    where (($visible - $start) mod $interval) eq 0 
    return
        $visible
};

let $task := task:fmap(
    task:fmap(
        task:of(util:system-time#0),
        fn:year-from-date#1
    ),
    local:hayleys-sightings#1
)
return

    task:RUN-UNSAFE($task)
                                    </programlisting>
                                </example>
                            </listitem>
                        </varlistentry>
                    </variablelist>
                </sect3>
            </sect2>
        </sect1>
    </appendix>

    <bibliography>
        
        <biblioentry xml:id="bib_xpath10">
            <editor>
                <personname>
                    <firstname>James</firstname>
                    <surname>Clark</surname>
                </personname>
            </editor>
            <editor>
                <personname>
                    <firstname>Steve</firstname>
                    <surname>DeRose</surname>
                </personname>
            </editor>
            <title>XML Path Language (XPath) Version 1.0</title>
            <edition>W3C Recommendation 16 November 1999 (Status updated October 2016)</edition>
            <date>1999-11-16</date>
            <bibliosource>
                <link xlink:href="https://www.w3.org/TR/1999/REC-xpath-19991116/"/>
            </bibliosource>
        </biblioentry>
        
        <biblioentry xml:id="bib_xpath20">
            <editor>
                <personname>
                    <firstname>Anders</firstname>
                    <surname>Berglund</surname>
                </personname>
            </editor>
            <editor>
                <personname>
                    <firstname>Scott</firstname>
                    <surname>Boag</surname>
                </personname>
            </editor>
            <editor>
                <personname>
                    <firstname>Mary</firstname>
                    <surname>Fernández</surname>
                </personname>
            </editor>
            <editor>
                <personname>
                    <firstname>Scott</firstname>
                    <surname>Boag</surname>
                </personname>
            </editor>
            <editor>
                <personname>
                    <firstname>Michael</firstname>
                    <surname>Kay</surname>
                </personname>
            </editor>
            <editor>
                <personname>
                    <firstname>Jonathan</firstname>
                    <surname>Robie</surname>
                </personname>
            </editor>
            <editor>
                <personname>
                    <firstname>Jérôme</firstname>
                    <surname>Siméon</surname>
                </personname>
            </editor>
            <title>XML Path Language (XPath) 2.0 (Second Edition)</title>
            <edition>W3C Recommendation 14 December 2010 (Link errors corrected 3 January 2011; Status updated October 2016)</edition>
            <date>2010-12-14</date>
            <bibliosource>
                <link xlink:href="https://www.w3.org/TR/xpath20/"/>
            </bibliosource>
        </biblioentry>
        
        <biblioentry xml:id="bib_xpath20_req">
            <editor>
                <personname>
                    <firstname>Mary</firstname>
                    <surname>Fernandez</surname>
                </personname>
            </editor>
            <editor>
                <personname>
                    <firstname>K</firstname>
                    <surname>Karun</surname>
                </personname>
            </editor>
            <editor>
                <personname>
                    <firstname>Mark</firstname>
                    <surname>Scardina</surname>
                </personname>
            </editor>
            <title>XPath Requirements Version 2.0</title>
            <edition>W3C Working Draft 3 June 2005</edition>
            <date>2005-06-03</date>
            <bibliosource>
                <link xlink:href="https://www.w3.org/TR/xpath20req/"/>
            </bibliosource>
        </biblioentry>
        
        <biblioentry xml:id="bib_xpath20_fs">
            <editor>
                <personname>
                    <firstname>Denise</firstname>
                    <surname>Draper</surname>
                </personname>
            </editor>
            <editor>
                <personname>
                    <firstname>Peter</firstname>
                    <surname>Fankhauser</surname>
                </personname>
            </editor>
            <editor>
                <personname>
                    <firstname>Mary</firstname>
                    <surname>Fernández</surname>
                </personname>
            </editor>
            <editor>
                <personname>
                    <firstname>Ashok</firstname>
                    <surname>Malhotra</surname>
                </personname>
            </editor>
            <editor>
                <personname>
                    <firstname>Kristoffer</firstname>
                    <surname>Rose</surname>
                </personname>
            </editor>
            <editor>
                <personname>
                    <firstname>Michael</firstname>
                    <surname>Rys</surname>
                </personname>
            </editor>
            <editor>
                <personname>
                    <firstname>Jérôme</firstname>
                    <surname>Siméon</surname>
                </personname>
            </editor>
            <editor>
                <personname>
                    <firstname>Philip</firstname>
                    <surname>Wadler</surname>
                </personname>
            </editor>
            <title>XQuery 1.0 and XPath 2.0 Formal Semantics (Second Edition)</title>
            <edition>W3C Recommendation 14 December 2010 (revised 7 September 2015)</edition>
            <date>2015-09-07</date>
            <bibliosource>
                <link xlink:href="https://www.w3.org/TR/xquery-semantics/"/>
            </bibliosource>
        </biblioentry>
        
        <biblioentry xml:id="bib_xslt20_req">
            <editor>
                <personname>
                    <firstname>Steve</firstname>
                    <surname>Muench</surname>
                </personname>
            </editor>
            <editor>
                <personname>
                    <firstname>Mark</firstname>
                    <surname>Scardina</surname>
                </personname>
            </editor>
            <title>XSLT Requirements Version 2.0</title>
            <edition>W3C Working Draft 14 February 2001</edition>
            <date>2001-02-14</date>
            <bibliosource>
                <link xlink:href="https://www.w3.org/TR/xslt20req/"/>
            </bibliosource>
        </biblioentry>
        
        <biblioentry xml:id="bib_xquery10_req">
            <editor>
                <personname>
                    <firstname>Don</firstname>
                    <surname>Chamberlin</surname>
                </personname>
            </editor>
            <editor>
                <personname>
                    <firstname>Peter</firstname>
                    <surname>Fankhauser</surname>
                </personname>
            </editor>
            <editor>
                <personname>
                    <firstname>Massimo</firstname>
                    <surname>Marchiori</surname>
                </personname>
            </editor>
            <editor>
                <personname>
                    <firstname>Jonathan</firstname>
                    <surname>Robie</surname>
                </personname>
            </editor>
            <title>XML Query (XQuery) Requirements</title>
            <edition>W3C Working Group Note 23 March 2007</edition>
            <date>2007-03-27</date>
            <bibliosource>
                <link xlink:href="https://www.w3.org/TR/xquery-requirements/"/>
            </bibliosource>
        </biblioentry>
        
        <biblioentry xml:id="bib_xquery_update30_puls">
            <editor>
                <personname>
                    <firstname>John</firstname>
                    <surname>Snelson</surname>
                </personname>
            </editor>
            <editor>
                <personname>
                    <firstname>Jim</firstname>
                    <surname>Melton</surname>
                </personname>
            </editor>
            <title>XQuery Update Facility 3.0</title>
            <subtitle>Pending Update Lists</subtitle>
            <edition>W3C Working Group Note 24 January 2017</edition>
            <date>2017-01-24</date>
            <bibliosource>
                <link xlink:href="https://www.w3.org/TR/xquery-update-30/#id-pending-update-lists"/>
            </bibliosource>
        </biblioentry>
        
        <biblioentry xml:id="bib_basex_jobs">
            <author>
                <personname>
                    <firstname>Christian</firstname>
                    <surname>Grün</surname>
                </personname>
            </author>
            <orgname>BaseX</orgname>
            <date>2018-10-31T16:11:00Z</date>
            <title role="wiki article">Jobs Module</title>
            <publisher>
                <publishername>BaseX</publishername>
            </publisher>
            <bibliosource>
                <link xlink:href="http://docs.basex.org/wiki/Jobs_Module"/>
            </bibliosource>
        </biblioentry>
        
        <biblioentry xml:id="bib_exist_eval-async">
            <author>
                <personname>
                    <firstname>Adam</firstname>
                    <surname>Retter</surname>
                </personname>
            </author>
            <orgname>eXist-db</orgname>
            <title>eXist-db Util XQuery Module</title>
            <publisher>
                <publishername>Git Hub</publishername>
            </publisher>
            <bibliosource>
                <link xlink:href="http://www.exist-db.org/exist/apps/fundocs/view.html?uri=http://exist-db.org/xquery/util&amp;location=java:org.exist.xquery.functions.util.UtilModule&amp;details=true"/>
            </bibliosource>
        </biblioentry>
        
        <biblioentry xml:id="bib_exist_scheduler">
            <author>
                <personname>
                    <firstname>Adam</firstname>
                    <surname>Retter</surname>
                </personname>
            </author>
            <orgname>eXist-db</orgname>
            <title>eXist-db Scheduler XQuery Module</title>
            <publisher>
                <publishername>Git Hub</publishername>
            </publisher>
            <bibliosource>
                <link xlink:href="http://www.exist-db.org/exist/apps/fundocs/view.html?uri=http://exist-db.org/xquery/scheduler&amp;location=java:org.exist.xquery.modules.scheduler.SchedulerModule"/>
            </bibliosource>
        </biblioentry>
        
        <biblioentry xml:id="bib_ibm_power4">
            <orgname>IBM</orgname>
            <date>2012-03-07</date>
            <title>IBM100 - Power 4 : The First Multi-Core, 1GHz Processor</title>
            <bibliosource>
                <link xlink:href="https://www.ibm.com/ibm/history/ibm100/us/en/icons/power4/"/>
            </bibliosource>
        </biblioentry>
        
        <biblioentry xml:id="bib_perrone09">
            <author>
                <personname>
                    <firstname>Michael</firstname>
                    <surname>Perrone</surname>
                </personname>
            </author>
            <date>2009</date>
            <title>Multicore Programming Challenges</title>
            <orgname>IBM, TJ Watson Research Lab</orgname>
            <biblioid class="isbn">978-3-642-03868-6</biblioid>
            <biblioid class="doi">10.1007/978-3-642-03869-3_1</biblioid>
            <publishername>Springer</publishername>
            <bibliosource>
                <link xlink:href="https://link.springer.com/chapter/10.1007%2F978-3-642-03869-3_1"/>
            </bibliosource>
            <citetitle pubwork="journal">Euro-Par 2009 Parallel Processing, Lecture Notes in Computer Science</citetitle>
            <volumenum>5704</volumenum>
        </biblioentry>
        
        <biblioentry xml:id="bib_fonseca_11">
            <author>
                <personname>
                    <firstname>Pedro</firstname>
                    <surname>Fonseca</surname>
                </personname>
                <affiliation>
                    <orgname>Max Planck Institute for Software Systems (MPI-SWS)</orgname>
                </affiliation>
            </author>
            <author>
                <personname>
                    <firstname>Cheng</firstname>
                    <surname>Li</surname>
                </personname>
                <affiliation>
                    <orgname>Max Planck Institute for Software Systems (MPI-SWS)</orgname>
                </affiliation>
            </author>
            <author>
                <personname>
                    <firstname>Rodrigo</firstname>
                    <surname>Rodrigues</surname>
                </personname>
                <affiliation>
                    <orgname>Max Planck Institute for Software Systems (MPI-SWS)</orgname>
                </affiliation>
            </author>
            <date>2011-04-10</date>
            <title>Finding complex concurrency bugs in large multi-threaded applications</title>
            <citetitle pubwork="journal">EuroSys '11 Proceedings of the sixth conference on Computer systems</citetitle>
            <pagenums>215-228</pagenums>
            <publishername>ACM</publishername>
            <biblioid class="isbn">978-1-4503-0634-8</biblioid>
            <biblioid class="doi">10.1145/1966445.1966465</biblioid>
            <bibliosource>
                <link xlink:href="https://dl.acm.org/citation.cfm?id=1966465"/>
            </bibliosource>
        </biblioentry>
        
        <biblioentry xml:id="bib_loring17">
            <author>
                <personname>
                    <firstname>Matthew</firstname>
                    <surname>Loring</surname>
                </personname>
                <affiliation>
                    <orgname>Google Inc, USA</orgname>
                </affiliation>
            </author>
            <author>
                <personname>
                    <firstname>Mark</firstname>
                    <surname>Marron</surname>
                </personname>
                <affiliation>
                    <orgname>Microsoft Research, USA</orgname>
                </affiliation>
            </author>
            <author>
                <personname>
                    <firstname>Daan</firstname>
                    <surname>Leijen</surname>
                </personname>
                <affiliation>
                    <orgname>Microsoft Research, USA</orgname>
                </affiliation>
            </author>
            <date>2017-10-24</date>
            <title>Semantics of Asynchronous JavaScript</title>
            <citetitle pubwork="journal">DLS 2017 Proceedings of the 13th ACM SIGPLAN International Symposium on on Dynamic Languages table of contents</citetitle>
            <pagenums>51-62</pagenums>
            <publishername>ACM</publishername>
            <biblioid class="isbn">978-1-4503-5526-1</biblioid>
            <biblioid class="doi">10.1145/3133841.3133846</biblioid>
            <bibliosource>
                <link xlink:href="https://dl.acm.org/citation.cfm?id=3133846"/>
            </bibliosource>
        </biblioentry>
        
<!-- TODO figure our the best place to reference this useful paper... relate to the use of XSLT and XQuery in creating webapps - relevant to Saxon/JS's need for async -->  
        <biblioentry xml:id="bib_radoi15">
            <author>
                <personname>
                    <firstname>Cosmin</firstname>
                    <surname>Radoi</surname>
                </personname>
                <affiliation>
                    <orgname>University of Illinois</orgname>
                </affiliation>
            </author>
            <author>
                <personname>
                    <firstname>Stephan</firstname>
                    <surname>Herhut</surname>
                </personname>
                <affiliation>
                    <orgname>Intel Corporation</orgname>
                </affiliation>
            </author>
            <author>
                <personname>
                    <firstname>Jaswanth</firstname>
                    <surname>Sreeram</surname>
                </personname>
                <affiliation>
                    <orgname>Intel Corporation</orgname>
                </affiliation>
            </author>
            <author>
                <personname>
                    <firstname>Danny</firstname>
                    <surname>Dig</surname>
                </personname>
                <affiliation>
                    <orgname>Oregon State University</orgname>
                </affiliation>
            </author>
            <date>2015-01-24</date>
            <title>Are Web Applications Ready for Parallelism?</title>
            <citetitle pubwork="journal">Proceedings of the 20th ACM SIGPLAN Symposium on Principles and Practice of Parallel Programming</citetitle>
            <pagenums>289-290</pagenums>
            <publishername>ACM</publishername>
            <biblioid class="isbn">978-1-4503-3205-7</biblioid>
            <biblioid class="doi">10.1145/2688500.2700995</biblioid>
            <bibliosource>
                <link xlink:href="https://dl.acm.org/citation.cfm?id=2700995"/>
            </bibliosource> 
        </biblioentry>
        
        <biblioentry xml:id="bib_baker77">
            <author>
                <personname>
                    <firstname>Henry</firstname>
                    <othername>G.</othername>
                    <surname>Baker</surname>
                    <lineage>Jr.</lineage>
                </personname>
                <affiliation>
                    <orgname>Massachusetts Institute of Technology</orgname>
                </affiliation>
            </author>
            <author>
                <personname>
                    <firstname>Carl</firstname>
                    <surname>Hewitt</surname>
                </personname>
                <affiliation>
                    <orgname>Massachusetts Institute of Technology</orgname>
                </affiliation>
            </author>
            <date>1977-08-15</date>
            <title>The Incremental Garbage Collection of Processes</title>
            <citetitle pubwork="journal">Proceedings of the 1977 symposium on Artificial intelligence and programming languages</citetitle>
            <pagenums>55-59</pagenums>
            <publishername>ACM</publishername>
            <biblioid class="doi">10.1145/800228.806932</biblioid>
        </biblioentry>
        
        <biblioentry xml:id="bib_hibbard76">
            <author>
                <personname>
                    <firstname>Peter</firstname>
                    <surname>Hibbard</surname>
                </personname>
            </author>
            <date>1976</date>
            <title>Parallel Processing Facilities</title>
            <citetitle pubwork="journal">New Directions in Algorithmic Languages</citetitle>
            <pagenums>1-7</pagenums>
        </biblioentry>
        
        <biblioentry xml:id="bib_friedman76">
            <author>
                <personname>
                    <firstname>Daniel</firstname>
                    <surname>Friedman</surname>
                </personname>
                <affiliation>
                    <orgname>Indiana University, Computer Science Department</orgname>
                </affiliation>
            </author>
            <author>
                <personname>
                    <firstname>David</firstname>
                    <surname>Wise</surname>
                </personname>
                <affiliation>
                    <orgname>Indiana University, Computer Science Department</orgname>
                </affiliation>
            </author>
            <date>1976</date>
            <title>The Impact of Applicative Programming on Multiprocessing</title>
            <citetitle pubwork="journal">International Conference on Parallel Processing 1976</citetitle>
            <pagenums>263–272</pagenums>
            <publishername>ACM</publishername>
        </biblioentry>
        
        <biblioentry xml:id="bib_dean04">
            <author>
                <personname>
                    <firstname>Jeffrey</firstname>
                    <surname>Dean</surname>
                </personname>
                <affiliation>
                    <orgname>Google, Inc.</orgname>
                </affiliation>
            </author>
            <author>
                <personname>
                    <firstname>Sanjay</firstname>
                    <surname>Ghemawat</surname>
                </personname>
                <affiliation>
                    <orgname>Google, Inc.</orgname>
                </affiliation>
            </author>
            <date>2004</date>
            <title>MapReduce: Simplified Data Processing on Large Clusters</title>
            <citetitle pubwork="journal">OSDI'04: Sixth Symposium on Operating System Design and Implementation</citetitle>
            <pagenums>137-150</pagenums>
            <bibliosource>
                <link xlink:href="https://research.google.com/archive/mapreduce-osdi04.pdf"/>
            </bibliosource>
        </biblioentry>
        
        <biblioentry xml:id="bib_kay15">
            <author>
                <personname>
                    <firstname>Michael</firstname>
                    <surname>Kay</surname>
                </personname>
                <affiliation>
                    <orgname>Saxonica</orgname>
                </affiliation>
            </author>
            <date>2015-02-14</date>
            <title>Parallel Processing in the Saxon XSLT Processor</title>
            <citetitle pubwork="journal">XML Prague 2015 Conference Proceedings</citetitle>
            <biblioid class="isbn">978-80-260-7667-4</biblioid>
            <bibliosource>
                <link xlink:href="http://www.saxonica.com/papers/xmlprague-2015mhk.pdf"/>
            </bibliosource>
        </biblioentry>
        
        <biblioentry xml:id="bib_robie16">
            <author>
                <personname>
                    <firstname>Jonathan</firstname>
                    <surname>Robie</surname>
                </personname>
            </author>
            <date>2016-03-03T12:05:03-05:00</date>
            <publishername>EXPath Mailing List</publishername>
            <title>Re: [expath] Re: New Modules? Promise Module, Async Module</title>
            <bibliosource>
                <link xlink:href="https://groups.google.com/forum/#!msg/expath/Isjeez-5op4/-DCn-KJGBAAJ"/>
            </bibliosource>
        </biblioentry>
        
        <biblioentry xml:id="bib_delpratt13">
            <author>
                <personname>
                    <firstname>O'Neil</firstname>
                    <surname>Delpratt</surname>
                </personname>
                <affiliation>
                    <orgname>Saxonica</orgname>
                </affiliation>
            </author>
            <author>
                <personname>
                    <firstname>Michael</firstname>
                    <surname>Kay</surname>
                </personname>
                <affiliation>
                    <orgname>Saxonica</orgname>
                </affiliation>
            </author>
            <date>2013-08-06</date>
            <title>Interactive XSLT in the browser</title>
            <citetitle pubwork="journal">Balisage Series on Markup Technologies, vol. 10 (2013)</citetitle>
            <volumenum>10</volumenum>
            <biblioid class="doi">https://doi.org/10.4242/BalisageVol10.Delpratt01</biblioid>
            <bibliosource>
                <link xlink:href="https://www.balisage.net/Proceedings/vol10/html/Delpratt01/BalisageVol10-Delpratt01.html"/>
            </bibliosource>
        </biblioentry>
        
        <biblioentry xml:id="bib_retter18">
            <author>
                <personname>
                    <firstname>Adam</firstname>
                    <surname>Retter</surname>
                </personname>
                <affiliation>
                    <orgname>Evolved Binary</orgname>
                </affiliation>
            </author>
            <date>2018-10-03</date>
            <title>EXPath and Asynchronous HTTP</title>
            <bibliosource>
                <link xlink:href="https://blog.adamretter.org.uk/expath-and-asynchronous-http/"/>
            </bibliosource>
        </biblioentry>

        <biblioentry xml:id="bib_camacho-rodríguez15">
            <author>
                <personname>
                    <firstname>Jesús</firstname>
                    <surname>Camacho-Rodríguez</surname>
                </personname>
            </author>
            <author>
                <personname>
                    <firstname>Dario</firstname>
                    <surname>Colazzo</surname>
                </personname>
            </author>
            <author>
                <personname>
                    <firstname>Ioana</firstname>
                    <surname>Manolescu</surname>
                </personname>
            </author>
            <date>2015</date>
            <title>PAXQuery: Efficient Parallel Processing of Complex XQuery</title>
            <citetitle pubwork="journal">IEEE Transactions on Knowledge and Data Engineering</citetitle>
            <publishername>Institute of Electrical and Electronics Engineers</publishername>
            <pagenums>1977-1991</pagenums>
            <biblioid class="doi">10.1109/TKDE.2015.2391110</biblioid>
            <bibliosource>
                <link xlink:href="https://hal.archives-ouvertes.fr/hal-01162929/document"/>
            </bibliosource>
        </biblioentry>
        
        <biblioentry xml:id="bib_xqib">
            <author>
                <personname>
                    <firstname>Ghislain</firstname>
                    <surname>Fourny</surname>
                </personname>
            </author>
            <author>
                <personname>
                    <firstname>Donald</firstname>
                    <surname>Kossmann</surname>
                </personname>
            </author>
            <author>
                <personname>
                    <firstname>Markus</firstname>
                    <surname>Pilman</surname>
                </personname>
            </author>
            <author>
                <personname>
                    <firstname>Tim</firstname>
                    <surname>Kraska</surname>
                </personname>
            </author>
            <author>
                <personname>
                    <firstname>Daniela</firstname>
                    <surname>Florescu</surname>
                </personname>
            </author>
            <author>
                <personname>
                    <firstname>Darin</firstname>
                    <surname>Mcbeath</surname>
                </personname>
            </author>
            <citetitle>WWW 2009 MADRID! Track: XML and Web Data / Session: XML Querying XQuery in the Browser</citetitle>
            <date>2009-04-20</date>
            <title>XQuery in the Browser</title>
            <bibliosource>
                <link xlink:href="http://www2009.eprints.org/102/1/p1011.pdf"/>
            </bibliosource>    
        </biblioentry>

        <biblioentry xml:id="bib_fennel13">
            <author>
                <personname>
                    <firstname>Philip</firstname>
                    <surname>Fennell</surname>
                </personname>
            </author>
            <date>2013-06-15</date>
            <citetitle pubwork="journal">XML London 2013 Conference Proceedings</citetitle>
            <edition>1</edition>
            <biblioid class="isbn">978-0-9926471-0-0</biblioid>
            <title>Extremes of XML</title>
            <bibliosource>
                <link xlink:href="https://xmllondon.com/2013/xmllondon-2013-proceedings.pdf#page=80"/>
            </bibliosource>  
        </biblioentry>
        
        <biblioentry xml:id="bib_expath_bin10">
            <editor>
                <personname>
                    <firstname>Jirka</firstname>
                    <surname>Kosek</surname>
                </personname>
            </editor>
            <editor>
                <personname>
                    <firstname>John</firstname>
                    <surname>Lumley</surname>
                </personname>
            </editor>
            <date>2013-12-03</date>
            <title>Binary Module 1.0</title>
            <publisher>
                <publishername>EXPath</publishername>
            </publisher>
            <bibliosource>
                <link xlink:href="http://expath.org/spec/binary/1.0"/>
            </bibliosource>  
        </biblioentry>
        
        <biblioentry xml:id="bib_expath_file10">
            <editor>
                <personname>
                    <firstname>Christian</firstname>
                    <surname>Grün</surname>
                </personname>
            </editor>
            <date>2015-02-20</date>
            <title>File Module 1.0</title>
            <publisher>
                <publishername>EXPath</publishername>
            </publisher>
            <bibliosource>
                <link xlink:href="http://expath.org/spec/file/1.0"/>
            </bibliosource>  
        </biblioentry>
        
        <biblioentry xml:id="bib_basex_pul">
            <orgname>BaseX</orgname>
            <date>2018-08-26T16:13:04Z</date>
            <title role="wiki article">Concepts: Pending Update List</title>
            <publisher>
                <publishername>BaseX</publishername>
            </publisher>
            <bibliosource>
                <link xlink:href="http://docs.basex.org/wiki/XQuery_Update#Pending_Update_List"/>
            </bibliosource>
        </biblioentry>
        
        <biblioentry xml:id="bib_marklogic_xdmp-spawn">
            <orgname>MarkLogic</orgname>
            <date>2018</date>
            <title>xdmp:spawn — MarkLogic 9 Product Documentation</title>
            <publisher>
                <publishername>MarkLogic</publishername>
            </publisher>
            <bibliosource>
                <link xlink:href="https://docs.marklogic.com/xdmp:spawn?q=spawn&amp;v=9.0&amp;api=true"/>
            </bibliosource>
        </biblioentry>
        
        
        <biblioentry xml:id="bib_marklogic_cpf">
            <orgname>MarkLogic</orgname>
            <date>2018</date>
            <title>Developing Modules to Process Content (Content Processing Framework Guide) — MarkLogic 9 Product Documentation</title>
            <publisher>
                <publishername>MarkLogic</publishername>
            </publisher>
            <bibliosource>
                <link xlink:href="https://docs.marklogic.com/guide/cpf/modules"/>
            </bibliosource>
        </biblioentry>
        
        <biblioentry xml:id="bib_marklogic_admin-group-add-scheduled-task">
            <orgname>MarkLogic</orgname>
            <date>2018</date>
            <title>admin:group-add-scheduled-task — MarkLogic 9 Product Documentation</title>
            <publisher>
                <publishername>MarkLogic</publishername>
            </publisher>
            <bibliosource>
                <link xlink:href="https://docs.marklogic.com/admin:group-add-scheduled-task"/>
            </bibliosource>
        </biblioentry>
        
        <biblioentry xml:id="bib_marklogic_xdmp-set">
            <orgname>MarkLogic</orgname>
            <date>2018</date>
            <title>xdmp:set — MarkLogic 9 Product Documentation</title>
            <publisher>
                <publishername>MarkLogic</publishername>
            </publisher>
            <bibliosource>
                <link xlink:href="https://docs.marklogic.com/xdmp:set"/>
            </bibliosource>
        </biblioentry>
        
        <biblioentry xml:id="bib_marklogic_visibility">
            <orgname>MarkLogic</orgname>
            <date>2018</date>
            <title>Understanding Transactions in MarkLogic Server (Application Developer's Guide) — MarkLogic 9 Product Documentation</title>
            <subtitle>Visibility of Updates</subtitle>
            <publisher>
                <publishername>MarkLogic</publishername>
            </publisher>
            <bibliosource>
                <link xlink:href="https://docs.marklogic.com/guide/app-dev/transactions#id_85012"/>
            </bibliosource>
        </biblioentry>
        
        <biblioentry xml:id="bib_wright16">
            <author>
                <personname>
                    <firstname>James</firstname>
                    <surname>Wright</surname>
                </personname>
            </author>
            <date>2016-02-13</date>
            <citetitle pubwork="journal">XML Prague 2016 Conference Proceedings</citetitle>
            <edition>1</edition>
            <biblioid class="isbn">978-80-906259-0-7</biblioid>
            <title>Promises and Parallel XQuery Execution</title>
            <bibliosource>
                <link xlink:href="http://archive.xmlprague.cz/2016/files/xmlprague-2016-proceedings.pdf#page=151"/>
            </bibliosource>  
        </biblioentry>
        
        <biblioentry xml:id="bib_xqpromise">
            <author>
                <personname>
                    <firstname>James</firstname>
                    <surname>Wright</surname>
                </personname>
            </author>
            <title>xq-promise</title>
            <date>2016-04-29</date>
            <publisher>
                <publishername>Git Hub</publishername>
            </publisher>
            <bibliosource>
                <link xlink:href="https://github.com/james-jw/xq-promise"/>
            </bibliosource>
        </biblioentry>

        <biblioentry xml:id="bib_conway63">
            <author>
                <personname>
                    <firstname>Conway</firstname>
                    <surname>Melvin</surname>
                </personname>
            </author>
            <date>1963</date>
            <title>A Multiprocessor System Design</title>
            <publishername>ACM</publishername>
            <biblioid class="doi">10.1145/1463822.1463838</biblioid>
            <citetitle pubwork="journal">Proceedings of the November 12-14, 1963, Fall Joint Computer Conference</citetitle>
            <pagenums>139-146</pagenums>
        </biblioentry>

        <biblioentry xml:id="bib_mdn_promise-syntax">
            <date>2018-11-15T06:49:39Z</date>
            <title>Promise | MDN</title>
            <subtitle>Syntax</subtitle>
            <bibliosource>
                <link xlink:href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise#Syntax"/>
            </bibliosource>
        </biblioentry>
        
        <biblioentry xml:id="bib_ecma262">
            <date>2015</date>
            <edition>6th Edition</edition>
            <title>Standard ECMA-262</title>
            <subtitle>ECMAScript® 2015 Language Specification</subtitle>
            <publishername>Ecma International</publishername>
            <bibliosource>
                <link xlink:href="http://www.ecma-international.org/ecma-262/6.0/#sec-promise-executor"/>
            </bibliosource>
        </biblioentry>
        
        <biblioentry xml:id="bib_hewitt73">
            <author>
                <personname>
                    <firstname>Carl</firstname>
                    <surname>Hewitt</surname>
                </personname>
            </author>
            <author>
                <personname>
                    <firstname>Peter</firstname>
                    <surname>Bishop</surname>
                </personname>
            </author>
            <author>
                <personname>
                    <firstname>Richard</firstname>
                    <surname>Steiger</surname>
                </personname>
            </author>
            <date>1973</date>
            <title>A Universal Modular ACTOR Formalism for Artificial Intelligence</title>
            <citetitle pubwork="journal">Proceedings of the 3rd International Joint Conference on Artificial Intelligence</citetitle>
            <seriesvolnums>IJCAI'73</seriesvolnums>
            <pagenums>235-245</pagenums>
            <publishername>Morgan Kaufmann Publishers Inc.</publishername>
            <bibliosource>
                <link xlink:href="http://dl.acm.org/citation.cfm?id=1624775.1624804"/>
            </bibliosource>
        </biblioentry>
        
        <biblioentry xml:id="bib_armstrong07">
            <author>
                <personname>
                    <firstname>Joe</firstname>
                    <surname>Armstrong</surname>
                </personname>
            </author>
            <orgname>Ericsson AB</orgname>
            <date>2007</date>
            <title>A History of Erlang</title>
            <citetitle pubwork="journal">Proceedings of the Third ACM SIGPLAN Conference on History of Programming Languages</citetitle>
            <seriesvolnums>HOPL III</seriesvolnums>
            <pagenums>6-1--6-26</pagenums>
            <publishername>ACM</publishername>
            <biblioid class="isbn">978-1-59593-766-7</biblioid>
            <biblioid class="doi">10.1145/1238844.1238850</biblioid>
        </biblioentry>
        
        <biblioentry xml:id="bib_akka_actors">
            <orgname>Lightbend, Inc.</orgname>
            <title>Akka Documentation</title>
            <subtitle>Actors</subtitle>
            <date>2018-12-07T11:55:00Z</date>
            <bibliosource>
                <link xlink:href="https://doc.akka.io/docs/akka/2.5.19/actors.html"/>
            </bibliosource>
        </biblioentry>
        
        <biblioentry xml:id="bib_wikipedia_actormodel">
            <date>2019-01-17T21:11:00Z</date>
            <title>Actor model</title>
            <subtitle>Actor libraries and frameworks</subtitle>
            <publishername>Wikipedia</publishername>
            <bibliosource>
                <link xlink:href="https://en.wikipedia.org/wiki/Actor_model#Actor_libraries_and_frameworks"/>
            </bibliosource>
        </biblioentry>
        
        <biblioentry xml:id="bib_hejlsberg10">
            <author>
                <personname>
                    <firstname>Anders</firstname>
                    <surname>Hejlsberg</surname>
                </personname>
            </author>
            <orgname>Microsoft</orgname>
            <date>2010-10-28T10:13:00Z</date>
            <publishername>Channel 9</publishername>
            <title>Introducing Async – Simplifying Asynchronous Programming</title>
            <bibliosource>
                <link xlink:href="https://channel9.msdn.com/Blogs/Charles/Anders-Hejlsberg-Introducing-Async"/>
            </bibliosource> 
        </biblioentry>
        
        <biblioentry xml:id="bib_syme07">
            <author>
                <personname>
                    <firstname>Don</firstname>
                    <surname>Syme</surname>
                </personname>
            </author>
            <orgname>Microsoft Research</orgname>
            <date>2007-10-10</date>
            <title>Introducing F# Asynchronous Workflows</title>
            <bibliosource>
                <link xlink:href="https://blogs.msdn.microsoft.com/dsyme/2007/10/10/introducing-f-asynchronous-workflows/"/>
            </bibliosource>
        </biblioentry>
        
        <biblioentry xml:id="bib_marlow12">
            <author>
                <personname>
                    <firstname>Simon</firstname>
                    <surname>Marlow</surname>
                </personname>
            </author>            
            <date>2012</date>
            <title>async-2.2.1: Run IO operations asynchronously and wait for their results</title>
            <subtitle>Control.Concurrent.Async</subtitle>
            <publishername>Hackage</publishername>
            <bibliosource>
                <link xlink:href="http://hackage.haskell.org/package/async/docs/Control-Concurrent-Async.html"/>
            </bibliosource>
        </biblioentry>
        
        <biblioentry xml:id="bib_gaafar17">
            <author>
                <personname>
                    <firstname>Mostafa</firstname>
                    <surname>Gaafar</surname>
                </personname>
            </author>
            <date>2017-03-26</date>
            <title>6 Reasons Why JavaScript’s Async/Await Blows Promises Away (Tutorial)</title>
            <publishername>Hacker Noon</publishername>
            <bibliosource>
                <link xlink:href="https://hackernoon.com/6-reasons-why-javascripts-async-await-blows-promises-away-tutorial-c7ec10518dd9"/>
            </bibliosource>
        </biblioentry>
        
        <biblioentry xml:id="bib_kantor19">
            <author>
                <personname>
                    <firstname>Ilya</firstname>
                    <surname>Kantor</surname>
                </personname>
            </author>
            <date>2019</date>
            <title>Promises, async/await</title>
            <subtitle>Async/await</subtitle>
            <publishername>JavaScript.info</publishername>
            <bibliosource>
                <link xlink:href="https://javascript.info/async-await"/>
            </bibliosource>
        </biblioentry>
        
        <biblioentry xml:id="bib_conway6307">
            <author>
                <personname>
                    <firstname>Melvin</firstname>
                    <surname>Conway</surname>
                </personname>
            </author>
            <date>1963-07</date>
            <title>Design of a Separable Transition-diagram Compiler</title>
            <citetitle pubwork="journal">ACM Communications</citetitle>
            <volumenum>6</volumenum>
            <pagenums>396-408</pagenums>
            <biblioid class="doi">10.1145/366663.366704</biblioid>
            <publishername>ACM</publishername>
        </biblioentry>
        
        <biblioentry xml:id="bib_unity18">
            <orgname>Unity Technologies</orgname>
            <date>2018</date>
            <title>Unity - Manual: Coroutines</title>
            <bibliosource>
                <link xlink:href="https://docs.unity3d.com/Manual/Coroutines.html"/>
            </bibliosource>
        </biblioentry>
        
        <biblioentry xml:id="bib_cooper12">
            <author>
                <personname>
                    <firstname>Harold</firstname>
                    <surname>Coopper</surname>
                </personname>
            </author>
            <date>2012-12</date>
            <title>Coroutine Event Loops in Javascript</title>
            <bibliosource>
                <link xlink:href="https://x.st/javascript-coroutines/"/>
            </bibliosource>
        </biblioentry>
        
        <biblioentry xml:id="bib_kotlin18">
            <orgname>Kotlin</orgname>
            <date>2018-12-06</date>
            <title>Kotlin Documentation</title>
            <subtitle>Shared mutable state and concurrency</subtitle>
            <publishername>GitHub</publishername>
            <bibliosource>
                <link xlink:href="https://github.com/Kotlin/kotlinx.coroutines/blob/1.1.1/docs/shared-mutable-state-and-concurrency.md"/>
            </bibliosource>
        </biblioentry>
        
        <biblioentry xml:id="bib_denicola12">
            <author>
                <personname>
                    <firstname>Domenic</firstname>
                    <surname>Denicola</surname>
                </personname>
            </author>
            <date>2012-10-14</date>
            <title>You're Missing the Point of Promises</title>
            <bibliosource>
                <link xlink:href="https://blog.domenic.me/youre-missing-the-point-of-promises/"/>
            </bibliosource>
        </biblioentry>

        <biblioentry xml:id="bib_jones92">
            <author>
                <personname>
                    <firstname>Simon</firstname>
                    <othername>Peyton</othername>
                    <surname>Jones</surname>
                </personname>
            </author>
            <author>
                <personname>
                    <firstname>Philip</firstname>
                    <surname>Wadler</surname>
                </personname>
            </author>
            <date>1992</date>
            <pubdate>1993-01</pubdate>
            <title>Imperative Functional Programming</title>
            <publishername>ACM</publishername>
            <citetitle pubwork="journal">Proceedings of the 20th ACM SIGPLAN-SIGACT Symposium on Principles of Programming Languages</citetitle>
            <seriesvolnums>POPL '93</seriesvolnums>
            <pagenums>71-84</pagenums>
            <biblioid class="isbn">0-89791-560-7</biblioid>
            <biblioid class="doi">10.1145/158511.158524</biblioid>
            <bibliosource>
                <link xlink:href="https://www.microsoft.com/en-us/research/wp-content/uploads/1993/01/imperative.pdf"/>
            </bibliosource>
        </biblioentry>
        
        <!--
            The use of monads to structure functional programs is described. Monads provide a convenient framework for simulating effects
            found in other languages, such as global state, exception handling, output, or non-determinism. Three case studies are looked at in detail: how
            monads ease the modification of a simple evaluator; how monads act as
            the basis of a datatype of arrays subject to in-place update; and how
            monads can be used to build parsers.
        -->
        <!--
        <biblioentry xml:id="bib_wadler92">
            <author><personname><firstname>Philip</firstname><surname>Wadler</surname></personname><affiliation><orgname>University of Glasgow</orgname></affiliation></author>
            <date>1992-08</date>
            <title>Monads for Functional Programming</title>
            <citetitle pubwork="journal">Program Design Calculi, Proceedings of the Marktoberdorf Summer School</citetitle>
            <bibliosource><link xlink:href="https://homepages.inf.ed.ac.uk/wadler/papers/marktoberdorf/baastad.pdf"/></bibliosource>
        </biblioentry>
        -->
        
        <biblioentry xml:id="bib_hudak07">
            <author>
                <personname>
                    <firstname>Paul</firstname>
                    <surname>Hudak</surname>
                </personname>
            </author>
            <author>
                <personname>
                    <firstname>John</firstname>
                    <surname>Hughes</surname>
                </personname>
            </author>
            <author>
                <personname>
                    <firstname>Simon</firstname>
                    <othername>Peyton</othername>
                    <surname>Jones</surname>
                </personname>
            </author>
            <author>
                <personname>
                    <firstname>Philip</firstname>
                    <surname>Wadler</surname>
                </personname>
            </author>
            <date>2007-04-16</date>
            <title>A History of Haskell: Being Lazy with Class</title>
            <citetitle pubwork="journal">Proceedings of the Third ACM SIGPLAN Conference on History of Programming Languages</citetitle>
            <seriesvolnums>HOPL III</seriesvolnums>
            <pagenums>12-1--12-55</pagenums>
            <biblioid class="isbn">978-1-59593-766-7</biblioid>
            <biblioid class="doi">10.1145/1238844.1238856</biblioid>
            <publishername>ACM</publishername>
            <bibliosource>
                <link xlink:href="https://www.microsoft.com/en-us/research/wp-content/uploads/2016/07/history.pdf"/>
            </bibliosource>
        </biblioentry>
        
        
        <biblioentry xml:id="bib_haskell10">
            <orgname>The University of Glasgow</orgname>            
            <date>2010</date>
            <title>base-4.12.0.0: Basic libraries</title>
            <subtitle>Control.Concurrent</subtitle>
            <publishername>Hackage</publishername>
            <bibliosource>
                <link xlink:href="http://hackage.haskell.org/package/base/docs/Control-Concurrent.html#v:forkIO"/>
            </bibliosource>
        </biblioentry>
        
        <biblioentry xml:id="bib_goes17">
            <author>
                <personname>
                    <firstname>John</firstname>
                    <othername>A</othername>
                    <surname>De Goes</surname>
                </personname>
            </author>
            <date>2017-09-16</date>
            <title>There Can Be Only One...IO Monad</title>
            <bibliosource>
                <link xlink:href="http://degoes.net/articles/only-one-io"/>
            </bibliosource>
        </biblioentry>
        
        <biblioentry xml:id="bib_monix18">
            <author>
                <personname>
                    <firstname>Alexandru</firstname>
                    <surname>Nedelcu</surname>
                </personname>
            </author>
            <date>2018-11-09</date>
            <title>Task - Monix</title>
            <subtitle>Documentation</subtitle>
            <publishername>GitHub</publishername>
            <bibliosource>
                <link xlink:href="https://monix.io/docs/3x/eval/task.html"/>
            </bibliosource>
        </biblioentry>
        
        <biblioentry xml:id="bib_reactive17">
            <author>
                <personname>
                    <firstname>Viktor</firstname>
                    <surname>Klang</surname>
                </personname>
            </author>
            <orgname>Lightbend, Inc.</orgname>
            <pubdate>2017-12-19</pubdate>
            <title>Reactive Streams</title>
            <publishername>GitHub</publishername>
            <bibliosource>
                <link xlink:href="http://www.reactive-streams.org/"/>
            </bibliosource>
        </biblioentry>
        
        <biblioentry xml:id="bib_eventloop18">
            <orgname>Mozilla</orgname>
            <pubdate>2018-09-23T04:04:54Z</pubdate>
            <title>JavaScript - Concurrency model and Event Loop</title>
            <publishername>Mozilla</publishername>
            <bibliosource>
                <link xlink:href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop"/>
            </bibliosource>
        </biblioentry>
        
        <biblioentry xml:id="bib_retter_xqpromise18">
            <author>
                <personname>
                    <firstname>Adam</firstname>
                    <surname>Retter</surname>
                </personname>
                <affiliation>
                    <orgname>Evolved Binary</orgname>
                </affiliation>
            </author>
            <title>xq-promise Terminology vs. JavaScript/jQuery</title>
            <date>2018-11-30</date>
            <publishername>GitHub</publishername>
            <bibliosource>
                <link xlink:href="https://github.com/james-jw/xq-promise/issues/19"/>
            </bibliosource>
        </biblioentry>
        
        <biblioentry xml:id="bib_retter19">
            <author>
                <personname>
                    <firstname>Adam</firstname>
                    <surname>Retter</surname>
                </personname>
                <affiliation>
                    <orgname>Evolved Binary</orgname>
                </affiliation>
            </author>
            <date>2019-01-13</date>
            <title>Haskell I/O and XPath</title>
            <bibliosource>
                <link xlink:href="https://blog.adamretter.org.uk/haskell-io-and-xpath/"/>
            </bibliosource>
        </biblioentry>
        
        <biblioentry xml:id="bib_ghelli06">
            <author>
                <personname>
                    <firstname>Giorgio</firstname>
                    <surname>Ghelli</surname>
                </personname>
                <affiliation>
                    <orgname>Universita di Pisa</orgname>
                </affiliation>
            </author>
            <author>
                <personname>
                    <firstname>Christopher</firstname>
                    <surname>Ré</surname>
                </personname>
                <affiliation>
                    <orgname>University of Washington</orgname>
                </affiliation>
            </author>
            <author>
                <personname>
                    <firstname>Jérôme</firstname>
                    <surname>Siméon</surname>
                </personname>
                <affiliation>
                    <orgname>IBM T.J. Watson Research Center</orgname>
                </affiliation>
            </author>
            <date>2006</date>
            <title>XQuery!: An XML query language with side effects</title>
            <citetitle pubwork="journal">Current Trends in Database Technology -- EDBT 2006</citetitle>
            <publishername>Springer Berlin Heidelberg</publishername>
            <pagenums>178-191</pagenums>
            <biblioid class="isbn">978-3-540-46790-8</biblioid>
        </biblioentry>
        
        <biblioentry xml:id="bib_saxon_tuple-types">
            <orgname>Saxonica</orgname>
            <date>2018-12-06</date>
            <title>Saxon Documentation</title>
            <subtitle>Tuple types</subtitle>
            <publishername>Saxonica</publishername>
            <bibliosource>
                <link xlink:href="http://www.saxonica.com/documentation/index.html#!extensions/syntax-extensions/tuple-types"/>
            </bibliosource>
        </biblioentry>

    </bibliography>
    
</article>