http://mathling.com/noise/annotations  library module

http://mathling.com/noise/annotations


Noise annotations
Since we can't use function annotations in Saxon-JS because we don't have
saxon:xquery, and it is awkward to do so in XSLT; use callable wrappers. They're
more portable, but less type-safe. Drat.
Since the function instance of tests always return true for the
anonymous functions for some reason, we have to split ann:f() into
ann:fp() and ann:fv() and add a marker to the callable. This means you
can't rely on adhoc functions working, which is a damned shame.

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

March 2023
Status: New

Function Index

Imports

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

Functions

Function: is-noise
declare function is-noise($f as item()) as xs:boolean


is-noise()
Type checking

Params
  • f as item()
Returns
  • xs:boolean
declare function this:is-noise(
  $f as item()
) as xs:boolean
{
  ($f instance of map(*) and util:kind($f)="callable" and this:is-noise(callable:function($f))) or
  ($f instance of function(map(xs:string,item()*)) as xs:double) or
  ($f instance of function(xs:double*) as xs:double)
}

Function: is-noise-vector
declare function is-noise-vector($f as item()) as xs:boolean


is-noise-vector()
Type checking

Params
  • f as item()
Returns
  • xs:boolean
declare function this:is-noise-vector(
  $f as item()
) as xs:boolean
{
  ($f instance of map(*) and util:kind($f)="callable" and $f("is-vector")) or
  ($f instance of function(xs:double*) as xs:double)
}

Function: is-noise-point
declare function is-noise-point($f as item()) as xs:boolean


is-noise-point()
Type checking

Params
  • f as item()
Returns
  • xs:boolean
declare function this:is-noise-point(
  $f as item()
) as xs:boolean
{
  ($f instance of map(*) and util:kind($f)="callable" and not($f("is-vector"))) or
  ($f instance of function(map(xs:string,item()*)) as xs:double)
}

Function: fn
declare function fn($name as xs:string, $f as item(), $is-vector as xs:boolean) as map(*)


Make a noise function callable with a given name
The $is-vector is a workaround for a Saxon instance of bug, which seems
to think all my anonymous noise functions are instances of both
function(map(xs:string,item()*)) as xs:double and
function(xs:double*) as xs:double

Params
  • name as xs:string
  • f as item()
  • is-vector as xs:boolean
Returns
  • map(*)
declare function this:fn(
  $name as xs:string,
  $f as item(),
  $is-vector as xs:boolean
)  as map(*)
{
  if (not(callable:is-callable($f))) then errors:error("ML-BADARGS", ("f", $f)) else (),
  let $prior-name := util:function-name($f)
  return (
    if ($prior-name = ("[anon]", "", $name))
    then callable:named($name, callable:function($f))
    else callable:named($name||"("||$prior-name||")", callable:function($f))
  )=>map:put("is-vector", $is-vector)
}

Function: f
declare function f($name as xs:string, $f as item()) as map(*)

Params
  • name as xs:string
  • f as item()
Returns
  • map(*)
declare function this:f(
  $name as xs:string,
  $f as item()
) as map(*)
{
  this:fn($name, $f, false())
}

Function: fp
declare function fp($name as xs:string, $f as item()) as map(*)

Params
  • name as xs:string
  • f as item()
Returns
  • map(*)
declare function this:fp(
  $name as xs:string,
  $f as item()
) as map(*)
{
  this:fn($name, $f, false())
}

Function: fv
declare function fv($name as xs:string, $f as item()) as map(*)

Params
  • name as xs:string
  • f as item()
Returns
  • map(*)
declare function this:fv(
  $name as xs:string,
  $f as item()
) as map(*)
{
  this:fn($name, $f, true())
}

Function: f
declare function f($name as xs:string, $f as item(), $parms as item()*, $is-vector as xs:boolean) as map(*)


Make a noise function callable with an expanded name with parameter tracking
The $is-vector is a workaround for a Saxon instance of bug, which seems
to think all my anonymous noise functions are instances of both
function(map(xs:string,item()*)) as xs:double and
function(xs:double*) as xs:double

Params
  • name as xs:string
  • f as item()
  • parms as item()*
  • is-vector as xs:boolean
Returns
  • map(*)
declare function this:f(
  $name as xs:string,
  $f as item(),
  $parms as item()*,
  $is-vector as xs:boolean
) as map(*)
{
  if (not(callable:is-callable($f))) then errors:error("ML-BADARGS", ("f", $f)) else (),
  let $prior-name := util:function-name($f)
  let $new-name :=
    if ($prior-name = ("[anon]", "", $name))
    then $name||"("||string-join($parms!util:quote(.),",")||")"
    else $name||"("||$prior-name||"("||string-join($parms!util:quote(.),",")||"))"
  return callable:named($new-name, callable:function($f))=>map:put("is-vector", $is-vector)
}

Function: f
declare function f($name as xs:string, $f as item(), $parms as item()*) as map(*)

Params
  • name as xs:string
  • f as item()
  • parms as item()*
Returns
  • map(*)
declare function this:f(
  $name as xs:string,
  $f as item(),
  $parms as item()*
) as map(*)
{
  this:f($name, $f, $parms, false())
}

Function: fp
declare function fp($name as xs:string, $f as item(), $parms as item()*) as map(*)

Params
  • name as xs:string
  • f as item()
  • parms as item()*
Returns
  • map(*)
declare function this:fp(
  $name as xs:string,
  $f as item(),
  $parms as item()*
)  as map(*)
{
  this:f($name, $f, $parms, false())
}

Function: fv
declare function fv($name as xs:string, $f as item(), $parms as item()*) as map(*)

Params
  • name as xs:string
  • f as item()
  • parms as item()*
Returns
  • map(*)
declare function this:fv(
  $name as xs:string,
  $f as item(),
  $parms as item()*
)  as map(*)
{
  this:f($name, $f, $parms, true())
}

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

Params
  • f as item()
Returns
  • function(*)
declare function this:function(
  $f as item()
) as function(*)
{
  callable:function($f)
}

Original Source Code

xquery version "3.1";
(:~
 : Noise annotations
 : Since we can't use function annotations in Saxon-JS because we don't have
 : saxon:xquery, and it is awkward to do so in XSLT; use callable wrappers. They're
 : more portable, but less type-safe. Drat.
 : Since the function instance of tests always return true for the
 : anonymous functions for some reason, we have to split ann:f() into
 : ann:fp() and ann:fv() and add a marker to the callable. This means you
 : can't rely on adhoc functions working, which is a damned shame.
 :
 : Copyright© Mary Holstege 2023-2025
 : CC-BY (https://creativecommons.org/licenses/by/4.0/)
 : @since March 2023
 : @custom:Status New
 :)
module namespace this="http://mathling.com/noise/annotations";

declare namespace map="http://www.w3.org/2005/xpath-functions/map";
declare namespace array="http://www.w3.org/2005/xpath-functions/array";
declare namespace math="http://www.w3.org/2005/xpath-functions/math";

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

(:~
 : is-noise()
 : Type checking
 :)
declare function this:is-noise(
  $f as item()
) as xs:boolean
{
  ($f instance of map(*) and util:kind($f)="callable" and this:is-noise(callable:function($f))) or
  ($f instance of function(map(xs:string,item()*)) as xs:double) or
  ($f instance of function(xs:double*) as xs:double)
};

(:~
 : is-noise-vector()
 : Type checking
 :)
declare function this:is-noise-vector(
  $f as item()
) as xs:boolean
{
  ($f instance of map(*) and util:kind($f)="callable" and $f("is-vector")) or
  ($f instance of function(xs:double*) as xs:double)
};

(:~
 : is-noise-point()
 : Type checking
 :)
declare function this:is-noise-point(
  $f as item()
) as xs:boolean
{
  ($f instance of map(*) and util:kind($f)="callable" and not($f("is-vector"))) or
  ($f instance of function(map(xs:string,item()*)) as xs:double)
};

(:~
 : Make a noise function callable with a given name
 : The $is-vector is a workaround for a Saxon instance of bug, which seems
 : to think all my anonymous noise functions are instances of both
 : function(map(xs:string,item()*)) as xs:double and
 : function(xs:double*) as xs:double
 :)
declare function this:fn(
  $name as xs:string,
  $f as item(),
  $is-vector as xs:boolean
)  as map(*)
{
  if (not(callable:is-callable($f))) then errors:error("ML-BADARGS", ("f", $f)) else (),
  let $prior-name := util:function-name($f)
  return (
    if ($prior-name = ("[anon]", "", $name))
    then callable:named($name, callable:function($f))
    else callable:named($name||"("||$prior-name||")", callable:function($f))
  )=>map:put("is-vector", $is-vector)
};

declare function this:f(
  $name as xs:string,
  $f as item()
) as map(*)
{
  this:fn($name, $f, false())
};

declare function this:fp(
  $name as xs:string,
  $f as item()
) as map(*)
{
  this:fn($name, $f, false())
};

declare function this:fv(
  $name as xs:string,
  $f as item()
) as map(*)
{
  this:fn($name, $f, true())
};

(:~
 : Make a noise function callable with an expanded name with parameter tracking
 : The $is-vector is a workaround for a Saxon instance of bug, which seems
 : to think all my anonymous noise functions are instances of both
 : function(map(xs:string,item()*)) as xs:double and
 : function(xs:double*) as xs:double
 :)
declare function this:f(
  $name as xs:string,
  $f as item(),
  $parms as item()*,
  $is-vector as xs:boolean
) as map(*)
{
  if (not(callable:is-callable($f))) then errors:error("ML-BADARGS", ("f", $f)) else (),
  let $prior-name := util:function-name($f)
  let $new-name :=
    if ($prior-name = ("[anon]", "", $name))
    then $name||"("||string-join($parms!util:quote(.),",")||")"
    else $name||"("||$prior-name||"("||string-join($parms!util:quote(.),",")||"))"
  return callable:named($new-name, callable:function($f))=>map:put("is-vector", $is-vector)
};

declare function this:f(
  $name as xs:string,
  $f as item(),
  $parms as item()*
) as map(*)
{
  this:f($name, $f, $parms, false())
};

declare function this:fp(
  $name as xs:string,
  $f as item(),
  $parms as item()*
)  as map(*)
{
  this:f($name, $f, $parms, false())
};

declare function this:fv(
  $name as xs:string,
  $f as item(),
  $parms as item()*
)  as map(*)
{
  this:f($name, $f, $parms, true())
};

declare function this:function(
  $f as item()
) as function(*)
{
  callable:function($f)
};