xproc / 3.0-specification

A community-driven effort to define an XProc 3.0 specification (formerly 1.1)
http://spec.xproc.org/
33 stars 10 forks source link

Are the semantics of default inputs underspecified? #1100

Closed ndw closed 4 months ago

ndw commented 4 months ago

The canonical use case for default inputs is:

<p:declare-step type="ex:default">
  <p:input port="source">
    <p:inline><hello-world/></p:inline>
  </p:input>
  <p:output port="result" sequence="true"/>
  <p:identity/>
</p:declare-step>

If you run that pipeline (as your top-level pipeline) and you don’t provide any input on the source port, the result is <hello-world/>. (I hope there's nothing controversial about that!)

That’s kind of a special case, but we use default inputs in places where I don’t think that’s the case that applies.

All we say about default inputs is

If a runtime binding is provided for an input port, implementations must not attempt to dereference the default bindings.

That works for the case above, but it says nothing about how default inputs are used when configuring the connections during static analysis.

Assuming the same ex:default step as above, I think this pipeline produces an empty sequence:

  <p:declare-step>
    <p:output port="result" sequence="true"/>
    <ex:default>
      <p:with-input><p:empty/></p:with-input>
    </ex:default>
  </p:declare-step>

There’s an explicit binding for the source input, so that's used.

By similar reasoning, I think this pipeline produces an empty sequence:

  <p:declare-step>
    <p:input port="source" sequence="true"/>
    <p:output port="result" sequence="true"/>
    <ex:default/>
  </p:declare-step>

The input on ex:default is connected and so the default does not apply. If there’s no input provided for the outer pipeline’s input, the pipeline produces an empty sequence.

But what about these pipelines:

  <p:declare-step>
    <p:output port="result" sequence="true"/>
    <ex:default/>
  </p:declare-step>

and

  <p:declare-step>
    <p:input port="source"/>
    <p:output port="result" sequence="true"/>

    <p:sink/>

    <ex:default/>
  </p:declare-step>

One interpretation is that both of these pipelines should raise err:XS0003 because there’s no explicit binding for the source port on ex:default and there’s no default readable port.

However, we use default inputs on steps like p:archive in ways that strongly imply that if there’s no binding for, for example the manifest port, then its default is the empty sequence.

In order to justify that interpretation, I think we’d have to agree that the default input applies whenever there is no explicit binding and no default readable port. So both of the preceding examples do not raise an error and instead produce <hello-world/>.

But I don’t think the spec says that anywhere. Which interpretation is correct and does the spec say that anywhere?

xml-project commented 4 months ago

Just a question: I wonder whether we did change anything on default inputs from XProc 1.0 -> 3.0? So is there a point were the underspecification came in, or is it a legacy that was already in 1.0?

ndw commented 4 months ago

Good question. And it leads me to the answer in 16.2.1. Thank you.