http://mathling.com/core/cache  library module

http://mathling.com/core/cache


Generic caching wrappers for callables (up to 6 arguments).
Depends on %saxon:memo-function.

Copyright© Mary Holstege 2023
CC-BY (https://creativecommons.org/licenses/by/4.0/)

April 2023
Status: New

Imports

http://mathling.com/core/callable
import module namespace f="http://mathling.com/core/callable"
       at "../core/callable.xqy"
http://mathling.com/core/errors
import module namespace errors="http://mathling.com/core/errors"
       at "../core/errors.xqy"

Functions

Function: cache
declare function cache($f as item()) as item()


cache()
Cache a callable function.

Params
  • f as item(): either a function or a callable wrapper
Returns
  • item(): either a function or callable that has %saxon:memo-function wrapping
declare function this:cache($f as item()) as item()
{
  let $fn := f:function($f)
  let $is-callable := ($f instance of map(*)) and $f("kind")="callable"
  let $cached-f := 
    switch(function-arity($fn))
    case 1 return function ($arg1) { this:cache($fn, $arg1) }
    case 2 return function ($arg1, $arg2) { this:cache($fn, $arg1, $arg2) }
    case 3 return function ($arg1, $arg2, $arg3) { this:cache($fn, $arg1, $arg2, $arg3) }
    case 4 return function ($arg1, $arg2, $arg3, $arg4) { this:cache($fn, $arg1, $arg2, $arg3, $arg4) }
    case 5 return function ($arg1, $arg2, $arg3, $arg4, $arg5) { this:cache($fn, $arg1, $arg2, $arg3, $arg4, $arg5) }
    case 6 return function ($arg1, $arg2, $arg3, $arg4, $arg5, $arg6) { this:cache($fn, $arg1, $arg2, $arg3, $arg4, $arg5, $arg6) }
    default return $f
  return (
    if ($is-callable) then (
      if (function-arity($fn) <= 6) then (
        f:named(f:name($f), $cached-f)
      ) else $cached-f
    ) else (
      $cached-f
    )
  )
}

Original Source Code

xquery version "3.1";
(:~
 : Generic caching wrappers for callables (up to 6 arguments).
 : Depends on %saxon:memo-function.
 :
 : Copyright© Mary Holstege 2023
 : CC-BY (https://creativecommons.org/licenses/by/4.0/)
 : @since April 2023
 : @custom:Status New
 :)
module namespace this="http://mathling.com/core/cache"; 

import module namespace errors="http://mathling.com/core/errors"
       at "../core/errors.xqy";
import module namespace f="http://mathling.com/core/callable"
       at "../core/callable.xqy";
       
declare namespace art="http://mathling.com/art";
declare namespace map="http://www.w3.org/2005/xpath-functions/map";
declare namespace saxon="http://saxon.sf.net/";

(:~
 : cache()
 : Cache a callable function.
 :
 : @param $f: either a function or a callable wrapper
 : @return either a function or callable that has %saxon:memo-function wrapping
 :)
declare function this:cache($f as item()) as item()
{
  let $fn := f:function($f)
  let $is-callable := ($f instance of map(*)) and $f("kind")="callable"
  let $cached-f := 
    switch(function-arity($fn))
    case 1 return function ($arg1) { this:cache($fn, $arg1) }
    case 2 return function ($arg1, $arg2) { this:cache($fn, $arg1, $arg2) }
    case 3 return function ($arg1, $arg2, $arg3) { this:cache($fn, $arg1, $arg2, $arg3) }
    case 4 return function ($arg1, $arg2, $arg3, $arg4) { this:cache($fn, $arg1, $arg2, $arg3, $arg4) }
    case 5 return function ($arg1, $arg2, $arg3, $arg4, $arg5) { this:cache($fn, $arg1, $arg2, $arg3, $arg4, $arg5) }
    case 6 return function ($arg1, $arg2, $arg3, $arg4, $arg5, $arg6) { this:cache($fn, $arg1, $arg2, $arg3, $arg4, $arg5, $arg6) }
    default return $f
  return (
    if ($is-callable) then (
      if (function-arity($fn) <= 6) then (
        f:named(f:name($f), $cached-f)
      ) else $cached-f
    ) else (
      $cached-f
    )
  )
};

declare %private %saxon:memo-function function this:cache($f as function(*), $arg1 as item()*) as item()*
{
  $f($arg1)
};

declare %private %saxon:memo-function function this:cache($f as function(*), $arg1 as item()*, $arg2 as item()*) as item()*
{
  $f($arg1, $arg2)
};

declare %private %saxon:memo-function function this:cache($f as function(*), $arg1 as item()*, $arg2 as item()*, $arg3 as item()*) as item()*
{
  $f($arg1, $arg2, $arg3)
};

declare %private %saxon:memo-function function this:cache($f as function(*), $arg1 as item()*, $arg2 as item()*, $arg3 as item()*, $arg4 as item()*) as item()*
{
  $f($arg1, $arg2, $arg3, $arg4)
};

declare %private %saxon:memo-function function this:cache($f as function(*), $arg1 as item()*, $arg2 as item()*, $arg3 as item()*, $arg4 as item()*, $arg5 as item()*) as item()*
{
  $f($arg1, $arg2, $arg3, $arg4, $arg5)
};

declare %private %saxon:memo-function function this:cache($f as function(*), $arg1 as item()*, $arg2 as item()*, $arg3 as item()*, $arg4 as item()*, $arg5 as item()*, $arg6 as item()*) as item()*
{
  $f($arg1, $arg2, $arg3, $arg4, $arg5, $arg6)
};