Re: Variables/Parameters and Scoping

Hi Norm,

Norm Walsh wrote:
> / Alessandro Vernet <avernet@orbeon.com> was heard to say:
> | On 5/18/06, Alex Milowski <alex@milowski.org> wrote:
> |> <p:let default="input-1">
> |>
> |>     <!-- binds the 'x' parameter for the contained steps -->
> |>     <p:parameter name="x" value="blue"/>
> |>
> |>     <!-- selects from the default input and binds it to 'y' -->
> |>     <p:parameter name="y" select="/doc/title"/>
> |
> | Does this mean that if you want 'x' to be based on 'input-1' and 'y'
> | on 'input-2' then you need to nested <p:let>? As in:
> 
> I don't think so. Alex's original example included
> 
>    <!-- selects from the specified input and binds it to 'z' -->
>    <p:parameter name="z" input='input-2' select="/doc/@created"/>
> 
> I think the default on p:let is just a convenience. I'd propose
> dropping it.

If you drop the default on <p:let>, then why bother having <p:let> at 
all? It would then become purely a method of scoping 
parameters/variables; in that case I'd rather just say that 
<p:param>/<p:variable> elements have a scope that is all their following 
siblings and their descendants.

I think that we're going to want <p:for-each> to set the context node 
(and context position/size) in a similar way to <xsl:for-each>. So 
<p:for-each> would do the same job as <p:let>.

   <p:for-each select="$input-1">
     <p:variable name="x" value="blue" />
     <p:variable name="y" select="/doc/title" />
     <p:variable name="z" select="$input-2/doc/@created" />
     ...
   </p:for-each>

Using the <xsl:for-each> model has the obvious advantage of familiarity 
to XSLT users.

I think that the only difference is that if input-1 doesn't hold any 
documents then <p:let> would still run the nested steps whereas 
<p:for-each> wouldn't. I'm not convinced that's a problem, especially as 
users are probably going to want to test for a missing input-1 either way.

If we do have a separate <p:let>-like element, I'd rather it were called 
<p:with> (from its name, I'd expect <p:let> to actually set variables 
rather than be used to provide context for the contained expressions).

> | This would not allow an expression that uses *both* input-1 and
> | input-2, hence the proposal of introducing a function instead of the
> | 'labelref' attribute (similar to the instance() function introduced by
> | XForms):
> |
> |    <p:step>
> |        <p:with-parm name="a" select="expression using
> |            label('input-1') and label('input-2')"/>
> |    </p:step>
> 
> One of the reasons that I favor the approach of naming the document
> with a separate attribute is that it prevents expressions with this
> level of complexity.

I don't get it: as you point out, users can still build expressions that 
are precisely this computationally complex:

 >   <p:variable name="a1" document="input-1" select="expr1"/>
 >   <p:variable name="a2" document="input-2" select="expr2"/>
 >   <p:with-param name="a" select="expression using $a1 and $a2"/>

Is it that you just don't want to let them do it with a simple syntax?!?

> I think it's easy to explain and implement how an expression should be
> applied to a single document. Allowing expressions to access arbitrary
> documents makes things quite a bit trickier. Either every expression
> has to begin with a label('') function or one of the documents has to
> be identified as the initial context document. The former is tedious
> and the latter is confusing since it won't necessarily be obvious from
> the expression which context is the default.

I disagree that allowing expressions to access arbitrary documents makes 
things more tedious. Personally, I find:

   <p:with-param name="someName" document="someLabel"
                 select="someExpression" />

more tedious than:

   <p:with-param name="someName" select="$someLabel/someExpression" />

and I find:

   <p:variable name="a1" document="input-1" select="expr1"/>
   <p:variable name="a2" document="input-2" select="expr2"/>
   ...
   <p:with-param name="a" select="expression using $a1 and $a2"/>

much more tedious than:

   <p:with-param name="a"
     select="expression using $input-1/expr1 and $input-2/expr2" />

Again, I think most of our users are going to be familiar with XSLT: 
we'll benefit if we can use a syntax and semantics that's similar.

>   <p:with-param name="otherName" select="otherExpression"/>
> 
> Sets the parameter $otherName to the result of evaluating
> otherExpression with the context node set to an empty document node.

It seems a bit of a hack to have the context node set to an empty 
document node. I'd rather make it an error to reference the context 
node/position/size in this case (this is what happens in XPath 2.0 when 
the context item is a undefined).

> In this case, each individual expression is easy to understand and
> implement and there's nothing that prevents a user from building
> compound expressions if they need them:
> 
>   <p:variable name="a1" document="input-1" select="expr1"/>
>   <p:variable name="a2" document="input-2" select="expr2"/>
>   <p:with-param name="a" select="expression using $a1 and $a2"/>

 From the other perspective, even if we allow users to build complex 
expressions, it won't prevent users from using variables to build 
complex expressions from simpler ones if they desire.

Cheers,

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

Received on Monday, 22 May 2006 11:27:32 UTC