Re: Thinking about port set expressions and block expressions

On a different topic, I was thinking that we need to treat inputs and
outputs separately in the syntax when we declare flows and/or steps
(they might just be the same thing and one is just a black box
implementation).

declare flow
  [$in as document()] myfilter($mode as xs:QName, $params as map())
  [$out as document()]
{
    ...
};

and

declare step
   [$source as document(), $stylesheet as document()] xslt($mode as
xs:QName, $params as map())
   [$result as document(), $secondary as document()*];

or

declare flow
   [$source as document(), $stylesheet as document()] xslt($mode as
xs:QName, $params as map())
   [$result as document(), $secondary as document()*] external;

and so we get:

xproc version = "2.0";
inputs  $source as document-node();
outputs $result as document-node();

[$source] → [$in] λ() [$out] { if (xs:decimal($in/*/@version) < 2.0)
                            then [$in,"v1schema.xsd"] →
validate-with-xml-schema() ≫ $out
                            else [$in,"v2schema.xsd"] →
validate-with-xml-schema() ≫ $out }
          → [$out,"stylesheet.xsl"] → xslt()
≫ $result

(and, nice use of lambda!)

Then we need to explain to users that the square bracket syntax means
ordered lists and we have three kinds: port set expressions, port
declarations, and port bindings.


On Fri, Apr 15, 2016 at 8:29 AM, Norman Walsh <ndw@nwalsh.com> wrote:
> It's been a long time since we talked about the signatures for steps.
> Suppose we used square brackets there too:
>
>   declare step xslt($mode as xs:QName, $params as map())
>         [$source, $stylesheet; $result, $secondary]
>   {
>     ...
>   }
>
>   Aside: we seem to have some inconsistency about whether port names
>   have $-prefixes or not.
>
> I'm not sure it's syntactically the best thing ever, but ...
>
> Now we can say that a port set expression provides a mapping of
> readable ports for the step that follows:
>
>   [source="doc.xml", "style.xsl"] -> xslt()
>
> (I kind of like the arrow for readability but I think Henry's right,
> it has no purpose except readability.)
>
> I imagine that the semantics of that mapping are something like this:
>
> Given a set of readable ports and a set of input ports, you match up
> the named ones first then you match up the remaining ones in order.
>
> So each of the following binds source and stylesheet for the following
> xslt() step just as you'd expect:
>
>   [source="doc.xml", "style.xsl"] -> xslt()
>   [source="doc.xml", stylesheet="style.xsl"] -> xslt()
>   [stylesheet="style.xsl", source="doc.xml"] -> xslt()
>   ["doc.xml", "style.xsl"] -> xslt()
>
> For a case where the named and ordinal ones are "out of order":
>
>   [stylesheet="style.xsl", "doc.xml"] -> xslt()
>
> I think there are two alternatives. We can say that this binding works
> by matching up the stylesheet port by name and the source port from
> the remaining possibilities ordinally or we can make it an error
> because you have to "go backward" to make it work. (I can't think of a
> concise way to express the error condition, but I think I can see it
> pretty clearly.)
>
> I'm naturally inclined to prefer to make it an error, but I'm not sure
> that's the right thing because I don’t think we want to make extra
> ports an error. I think both:
>
>   [source="doc.xml", "style.xsl", "alt.xml"] -> xslt()
>   [source="doc.xml", alt="alt.xml", stylesheet="style.xsl"] -> xslt()
>
> bind source to "doc.xml" and stylesheet to "style.xsl" in the XSLT
> step. The extra binding is just ignored; there's no way for the XSLT
> step to read it.
>
> Another interesting case is when the names don't match up at all:
>
>   [result="doc.xml", "style.xsl"]
>
> I think the right answer here is to say that names which don't match
> are ignored. So the preceding port set expression is exactly
> equivalent to ["doc.xml", "style.xsl"] for a following xslt() step;
> if the following step has a 'result' input port then it gets doc.xml.
>
> Absent ports are just treated as empty:
>
>   [stylesheet="style.xsl"] -> xslt()
>
> binds the stylesheet to "style.xsl" and leaves the source input empty.
> I suppose you could also do that this way: [(), "style.xsl"] though
> I'm not sure we've worked out what kinds of expressions can go in a
> port set expression.
>
> The result of a step is, I think, a port set expression that binds
> the output ports to the results. So the xslt() step produces a binding
> that's equivalent to this:
>
>    [result="result.xml", secondary="secondary.xml"]
>
> By the rule that says that port names that don't match are simply
> ignored, we can still say that:
>
>    xslt() -> store(href="output.xml")
>
> would store "result.xml" into "output.xml" but would do nothing with
> the secondary output. If you want to remap things, you have to put in
> a port set expression.
>
>    xslt() -> [source=port("secondary")] -> store("secondary.xml")
>
> And it occurs to me that a port set expression doesn't even need
> the port() function if we say that it can refer to the names of
> readable ports directly:
>
>    xslt() -> [$secondary] -> store("secondary.xml")
>
> All of the preceding is back-formation from my idea for block
> expressions, which is to make them anonymous steps.
>
> xproc version = "2.0";
> inputs  $source as document-node();
> outputs $result as document-node();
>
> [$source] → λ()[$in;$out] { if (xs:decimal($in/*/@version) < 2.0)
>                             then [$in,"v1schema.xsd"] → validate-with-xml-schema() ≫ $out
>                             else [$in,"v2schema.xsd"] → validate-with-xml-schema() ≫ $out }
>           → [$out,"stylesheet.xsl"] → xslt()
> ≫ $result
>
> It's a little bit of extra syntax, but I think JavaScript and futures
> have made anonymous functions commonplace.
>
> They also afford some interesting flexibility, consider:
>
> xproc version = "2.0";
> inputs  $source as document-node();
> outputs $result as document-node();
> options $minver as xs:decimal := 2.0,
>         $v1schema := "v1schema.xsd",
>         $v2schema := "v2schema.xsd";
>
> [$source] → λ($vertest as xs:decimal := $minver,
>               $v1 as xs:string := $v1schema,
>               $v2 as xs:string := $v2schema)
>             [$in;$out]
>             { if (xs:decimal($in/*/@version) < $vertest)
>                             then [$in,$v1] → validate-with-xml-schema() ≫ $out
>                             else [$in,$v2] → validate-with-xml-schema() ≫ $out }
>           → [$out,"stylesheet.xsl"] → xslt()
> ≫ $result
>
> I'm not sure how useful that is, really, but ...
>
>                                         Be seeing you,
>                                           norm
>
> --
> Norman Walsh
> Lead Engineer
> MarkLogic Corporation
> Phone: +1 512 761 6676
> www.marklogic.com



-- 
--Alex Miłowski
"The excellence of grammar as a guide is proportional to the paucity of the
inflexions, i.e. to the degree of analysis effected by the language
considered."

Bertrand Russell in a footnote of Principles of Mathematics

Received on Friday, 15 April 2016 16:33:20 UTC