New test for function inlining: Saxon bug 2321
authordlockett <debbie@saxonica.com>
Thu, 14 Mar 2019 17:01:03 +0000
changeset 2055 9cbda28a541d
parent 2054 e3b9fc0f6ebb
child 2058 f207ef742e81
New test for function inlining: Saxon bug 2321
tests/expr/higher-order-functions/_higher-order-functions-test-set.xml
tests/expr/higher-order-functions/higher-order-functions-075.xsl
--- a/tests/expr/higher-order-functions/_higher-order-functions-test-set.xml	Thu Mar 14 16:00:52 2019 +0000
+++ b/tests/expr/higher-order-functions/_higher-order-functions-test-set.xml	Thu Mar 14 17:01:03 2019 +0000
@@ -966,6 +966,22 @@
          <assert>/out = '18 iv 1924'</assert>
       </result>
    </test-case>
+   
+   <test-case name="higher-order-functions-075">
+      <description>
+         Function inlining (Saxon bug 2321)
+      </description>
+      <created by="Debbie Lockett" on="2019-03-14"/>
+      <test>
+         <stylesheet file="higher-order-functions-075.xsl"/>
+         <initial-template name="ex1"/>
+      </test>
+      <result>
+         <all-of>
+            <assert-string-value>1234</assert-string-value>
+         </all-of>
+      </result>
+   </test-case>
 </test-set>
 
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/expr/higher-order-functions/higher-order-functions-075.xsl	Thu Mar 14 17:01:03 2019 +0000
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+  xmlns:xs="http://www.w3.org/2001/XMLSchema"
+  xmlns:fn="http://www.w3.org/2005/xpath-functions"
+  xmlns:map="http://www.w3.org/2005/xpath-functions/map"
+  xmlns:array="http://www.w3.org/2005/xpath-functions/array"
+  xmlns:io="http://expath.org/ns/io"
+  xmlns:task="http://expath.org/ns/task"
+  exclude-result-prefixes="#all"
+  version="3.0">
+  
+  <!-- Saxon bug #2321: Function inlining (performance check) -->
+  
+  <xsl:param name="realworldEl" as="element()">
+    <io:realworld/>
+  </xsl:param>
+  
+  <xsl:function name="task:create-monadic-task" as="map(*)">
+    <xsl:param name="apply-fn" as="function(*)"/>
+    <xsl:sequence select="map {
+      'apply': $apply-fn,
+      
+      'bind' : function($binder as function(item()*) as map(*)) as map(*) {
+      let $bound-apply-fn := function($realworld) {
+      let $io-res := $apply-fn($realworld)
+      return
+      $binder(fn:tail($io-res))('apply')(fn:head($io-res))
+      }
+      return
+      task:create-monadic-task($bound-apply-fn)
+      },
+      
+      'then': function($next as map(*)) as map(*) {
+      let $then-apply-fn := function($realworld) {
+      let $io-res := $apply-fn($realworld)
+      (: NOTE: the result given by fn:head($io-res)
+      is not needed by `then`, so we can ignore it :)
+      return
+      $next('apply')(fn:head($io-res))
+      }
+      return
+      task:create-monadic-task($then-apply-fn)
+      },
+      
+      
+      'fmap': function($mapper as function(item()*) as item()*) as map(*) {
+      let $fmap-apply-fn := function($realworld) {
+      let $io-res := $apply-fn($realworld)
+      return
+      (fn:head($io-res), $mapper(fn:tail($io-res)))
+      }
+      return
+      task:create-monadic-task($fmap-apply-fn)
+      },
+      
+      'async': function() as map(*) {
+      let $async-apply-fn := function($realworld as element(io:realworld)) as item() + {
+      let $exec-NO-async := $apply-fn($realworld), 
+      $async-a := function($scheduler as element(io:scheduler)) as item()+ {
+      ($scheduler, fn:tail($exec-NO-async))
+      }
+      return
+      (fn:head($exec-NO-async), $async-a)
+      }
+      return
+      task:create-monadic-task($async-apply-fn)
+      }
+      
+      
+      }"/>
+  </xsl:function>
+  
+  <xsl:function name="task:RUN-UNSAFE">
+    <xsl:param name="task" as="map(*)"/>
+    <xsl:sequence select="subsequence(
+      $task('apply')($realworldEl),
+      2
+      )"/>
+  </xsl:function>
+  
+  
+  <!-- Example 1:  Create a task from a pure value and run it -->
+  <xsl:template name="ex1">
+    <xsl:sequence select="task:RUN-UNSAFE(
+      task:create-monadic-task(function($realworld) {
+      ($realworld, 1234)
+      })
+      )"/>
+  </xsl:template>
+  
+  
+</xsl:stylesheet>