Previous: , Up: Higher-Order Functions   [Contents]


1.3 Ref API

function: element( f:ref ) f:make-ref (name as xs:QName, arity as xs:integer)

xmlns:f="http://mikegerwitz.com/hoxsl/apply"

Create a reference to dynamic function name with arity arity

This function does not verify that the function name exists, nor does it verify that the provided arity is valid for it. Further, the returned function reference will work only with dynamic functions—that is, an application template is needed. See transform/apply-gen.xsl for more information and examples.

Definition:

<function name="f:make-ref"  as="element( f:ref )">
  <param name="name"  as="xs:QName" />
  <param name="arity"  as="xs:integer" />

  <variable name="ns"  select="namespace-uri-from-QName( $name )" />

  <f:ref arity="{$arity}"  length="1">
    <element name="{$name}"  namespace="{$ns}" />
  </f:ref>
</function>
function: xs:boolean f:is-ref (fnref as item()*)

xmlns:f="http://mikegerwitz.com/hoxsl/apply"

Determines whether fnref represents a valid dynamic function reference

This can be used to determine if fnref is valid as input to other functions, some of which may produce an error if called with an invalid dynamic function reference.

Implementation details: To be valid, fnref must:

  1. Be an element of type f:ref;
  2. Have a numeric @arity; and
  3. Have a child target function node.

Definition:

<function name="f:is-ref"  as="xs:boolean">
  <param name="fnref"  as="item()*" />

  <variable name="ref"  select="$fnref[ 1 ]" />

  <!-- for @arity check: note that NaN != NaN -->
  <sequence select="$ref instance of element( f:ref ) and number( $ref/@arity ) = number( $ref/@arity ) and exists( $ref/*[ 1 ] )" />
</function>
function: xs:QName? f:QName (fnref as item()+)

xmlns:f="http://mikegerwitz.com/hoxsl/apply"

Retrieve the QName of the target dynamic function

Usually, this will match precisely the QName of the target function.

fnreF must be a valid dynamic function reference.

Implementation details: This actually represents the QName of the application template, which could differ from the target function name. One reason this may be the case is to provide a function alias.

Definition:

<function name="f:QName"  as="xs:QName?">
  <param name="fnref"  as="item()+" />

  <variable name="desc"  as="element( f:ref )"  select="$fnref[ 1 ]" />

  <variable name="target"  as="element()?"  select="$desc/element()[ 1 ]" />

  <sequence select="node-name( $target )" />
</function>
function: xs:integer f:arity (fnref as item()+)

xmlns:f="http://mikegerwitz.com/hoxsl/apply"

Attempt to retrieve arity of dynamic function fnref

fnref must be a dynamic function reference satisfying f:is-ref. Partially applied function references will have an arity equivalent to the free parameters in the target function.

Definition:

<function name="f:arity"  as="xs:integer">
  <param name="fnref"  as="item()+" />

  <variable name="ref"  as="element( f:ref )"  select="$fnref[ 1 ]" />

  <!-- this implicitly asserts on the type; it should never fail if
       the system is being used properly -->
  <variable name="arity"  as="xs:integer"  select="$ref/@arity" />

  <sequence select="$arity" />
</function>
function: item()* f:args (fnref as item()+)

xmlns:f="http://mikegerwitz.com/hoxsl/apply"

Retrieve a sequence of the partially applied arguments of fnref

The resulting sequence may be empty. fnref is assumed to be a valid dynamic function reference; you should verify that assumption beforehand.

Definition:

<function name="f:args"  as="item()*">
  <param name="fnref"  as="item()+" />

  <variable name="desc"  as="element( f:ref )"  select="$fnref[ 1 ]" />
  <variable name="length"  as="xs:double"  select="$desc/@length" />

  <sequence select="subsequence( $fnref, 2, ( $length - 1 ) )" />
</function>
function: item()+ f:set-args (fnref as item()+, args as item()*)

xmlns:f="http://mikegerwitz.com/hoxsl/apply"

Set partially applied arguments of fnref to args, replacing any existing arguments

The arity of fnref will be adjusted relative to the number of items in args such that the resulting dynamic function reference has the illusion of being its own, new function: increasing the argument count of fnref will decrease the arity of the resulting reference and vice versa.

No validations are performed on arity—if there exist more arguments than the number of target function parameters, no error will be raised.

fnref must be a valid dynamic function reference.

Definition:

<function name="f:set-args"  as="item()+">
  <param name="fnref"  as="item()+" />
  <param name="args"  as="item()*" />

  <variable name="desc"  as="element( f:ref )"  select="$fnref[ 1 ]" />

  <!-- this reference may be partially applied; see below arity
       adjustment -->
  <variable name="target-arity"  as="xs:double"  select="$desc/@arity + count( f:args( $fnref ) )" />

  <f:ref>
    <sequence select="$desc/@*" />

    <!-- treat partial applications as their own functions (with their
         own arities) -->
    <attribute name="arity"  select="$target-arity - count( $args )" />

    <attribute name="length"  select="count( $args ) + 1" />

    <sequence select="$desc/*" />
  </f:ref>

  <!-- be sure to retain the adjacent data (which is offset by the
       _original_ reference length) -->
  <sequence select="$args, subsequence( $fnref, $desc/@length + 1 )" />
</function>
function: item()+ f:push-args (fnref as item()+, args as item()*)

xmlns:f="http://mikegerwitz.com/hoxsl/apply"

Pushes args onto the argument list of fnref

This operates just as f:set-args, but retains existing arguments.

Definition:

<function name="f:push-args"  as="item()+">
  <param name="fnref"  as="item()+" />
  <param name="args"  as="item()*" />

  <sequence select="f:set-args($fnref, (f:args( $fnref ), $args) )" />
</function>
function: item()+ f:unshift-args (fnref as item()+, args as item()*)

xmlns:f="http://mikegerwitz.com/hoxsl/apply"

Unshifts args onto the argument list of fnref

This operates just as f:set-args, but retains existing arguments.

Definition:

<function name="f:unshift-args"  as="item()+">
  <param name="fnref"  as="item()+" />
  <param name="args"  as="item()*" />

  <sequence select="f:set-args($fnref, ($args, f:args( $fnref )) )" />
</function>
function: xs:double f:length (fnref as item()+)

xmlns:f="http://mikegerwitz.com/hoxsl/apply"

Retrieve length of fnref as a number of sequence items

While the reference is intended to be opaque, it is no secret that the data are stored as a sequence. The length is therefore important for stepping through that sequence of data, similar to how data/struct length are required for pointer arithmetic when dealing with memory in C.

So, this doesn’t break encapsulation: it just tells us how big we are, which is an external quality that can be easily discovered without our help; we just cache it for both performance and convenience. Aren’t we nice?

Definition:

<function name="f:length"  as="xs:double">
  <param name="fnref"  as="item()+" />

  <variable name="desc"  as="element( f:ref )"  select="$fnref[ 1 ]" />

  <sequence select="number( $desc/@length )" />
</function>

Previous: , Up: Higher-Order Functions   [Contents]