Re: Composability

Norman Walsh wrote:
> / ht@inf.ed.ac.uk (Henry S. Thompson) was heard to say:
> | Jeni Tennison writes:
> |
> |> Norman Walsh wrote:
> |>> / Jeni Tennison <jeni@jenitennison.com> was heard to say:
> |>> [...]
> |>> | and call this new pipeline in the same way as before:
> |>> |
> |>> |   <my:matching-documents xmlns:my="http://www.example.com/ns/jeni">
> |>> |     <p:option name="test" value="/my:foo[@bar = $bar]" />
> |>> |   </my:matching-documents>
> |>> |
> |>> | The value '/my:foo[@bar = $bar]' is passed as the value of the test
> |>> | option to <jt:matching-documents> as a string. But in my pipeline,
> |>> | where <p:matching-documents> is called, there's no binding for the
> |>> | 'my' prefix, nor for the $bar in-scope option, so the pipeline fails.
> |>> Perhaps we should allow options to be passed into called
> |>> pipelines. At
> |>> the moment, it's only forbidden by the special rules for constructing
> |>> the p:pipeline environment. We could fix that.
> |>> Then, if $bar is in scope for the pipeline that calls
> |>> my:matching-documents, it would be in scope for the step that
> |>> evaluates it. Options would be passed down.
> |>
> |> But then they shouldn't be options. The distinguishing feature of
> |> options is that they are predefined, and if you're passing in name/value
> |> pairs from the calling pipeline, then those pairs can't be known in advance.
> |
> | I'm not clear why that's at issue here.  We're talking about the
> | availability of option _bindings_ for discharging variable references
> | in XPaths, for which we've already established that all in-scope
> | option bindings are available.  The only question is, should named
> | pipelines be different from other steps in what constitutes the
> | in-scope bindings.  I agree with Norm that I can't see any reason why
> | there should be a difference, so the '$bar' part of your example
> | should work just fine.
> 
> The problem is that pipelines are defined externally so lexical scoping
> doesn't work.
> 
> Sure, this works:
> 
>   <p:pipeline>
>     <p:option name="bar" value="value"/>
> 
>     <p:group>
>       <p:option name="foo" select="$bar"/>
>     </p:group>
>   </p:pipeline>
> 
> But if the p:group is instead a pipeline, it looks like this:
> 
>   <p:pipeline>
>     <p:import href="some-library.xml"/>
>     <p:option name="bar" value="value"/>
> 
>     <px:pipeline/>
>   </p:pipeline>
> 
>   ...some-library.xml...
> 
>   <p:pipeline name="pipeline" namespace="px:">
>     <p:option name="foo" select="$bar"/>
>   </p:pipeline>
> 
> I think I expect the reference to $bar to be an error in that
> external pipeline.

Me too. I think Henry's saying that he wants dynamic scoping of options.

I think we need:

   (a) a way of getting at what in-scope options were available when a 
pipeline was invoked, from within the pipeline. A parameter set called 
'#pipeline-context-options' or something could do that job.

   (b) a way of passing a different set of in-scope options into a given 
step (or a way of switching the current in-scope options for another 
set, perhaps).

> | Namespaces are a different question, but my _inclination_ is to say
> | that we should at least consider what is from the _user_ perspective a
> | very simple statement: prefixes in XPath expressions in attribute
> | values in XProc pipeline documents are expanded wrt the namespace
> | bindings of their parent EII.  What implementations have to do to
> | achieve this is their problem.  At first blush, doesn't seem too bad
> | to me -- options whose values are XPaths (oops, here comes option
> | value typing again :-) have to carry their namespace binding context
> | with them.
> 
> That's what my implementation does and I haven't yet constructed an
> example where it doesn't work, but I haven't had time to try very hard
> either.

The situation that will trip you up, I think, is where the option's 
value is set based on the value of some attribute or element in a 
separate XML document.

So you have something like:

   <my:config xmlns:my="http://www.example.com/ns/my"
              xmlns:contact="http://www.example.com/ns/contact">
     <my:filter test="contact:person/contact:name = 'Jones'" />
   </my:config>

passed in on the config port and you do:

   <p:matching-documents>
     <p:option name="test" select="/my:config/my:filter/@test">
       <p:pipe step="top" source="config" />
     </p:option>
   </p:matching-documents>

The contact namespace isn't declared anywhere in your pipeline: you need 
to pick it up from the config document.

OK, so you think that's easy because you can detect that the option has 
been set from a node in a document so you just pick up the in-scope 
namespaces from that node. Now try this one:

   <p:matching-documents>
     <p:option name="test"
       select="concat('/xhtml:html/xhtml:head/rdf:RDF[',
                      /my:config/my:filter/@test, ']')">
       <p:pipe step="top" source="config" />
     </p:option>
   </p:matching-documents>

The namespace set needs to contain the in-scope namespaces from the 
config document *and* some namespaces from the pipeline environment (if 
those namespaces are even declared).

I just don't see a way that we can specify how a processor should do 
this: you need the intelligence of the person writing the pipeline to be 
able to tell which namespaces need to be used, which means we need:

   (a) a way of passing in namespace bindings to either a step (my 
preference) or individual options (which I think is too complicated).

   (b) a way of picking up the namespaces that were in scope when a 
pipeline was invoked

   (c) a way of getting the in-scope namespace declarations within a 
pipeline, in order to use those in the set that you then pass into 
another step (this can be done with a <p:namespaces> step analogous to 
the <p:parameters> one).

Jeni
-- 
Jeni Tennison
http://www.jenitennison.com

Received on Wednesday, 6 June 2007 21:18:59 UTC