XQuery needs to prohibit variable redefinition

(I'm told this issue has been brought up before.  However,
we now have experience: many people *do* make this mistake:
http://xquery.com/pipermail/talk/2004-July/000272.html
http://xquery.com/pipermail/talk/2004-July/000273.html )

PROPOSAL:

Add to 3.8.1 "For and Let Clauses" and 3.11 "Quantified Expressions"
wording similar to: "A static error is raised if the expanded QName of
any VarName being bound is the same as the expanded QName of one of
the existing in-scope variables."

MOTIVATION 1 (beginners):

The most common beginner confusion in XQuery is confusion about
variables, definitions, and assignments.  Here is a typical example:

   let $x := 0
     for $y in ...
       let $x := $x + ...
         ...

This kind of code happens because many people new to XQuery are
confused by the difference between binding and assignment, and
they're not familiar with hierarchical lexical scoping.

This is not a hypothetical program: We have all seen people asking why
this code doesn't work.  When companies deploy products they will
see many more such support calls.

A counter-argument (as paraphrased by Dana Florescu): "XQuery is not an
imperative language and LET is a variable definition, not a variable
assignment.  It's not by prohibiting small issues like this and
avoiding this kind of mistake this that will make them understand this
important fact."  And that is true.  However, if the language prohibits
redefinition, then the implementation can reject many of the more
common manifestations of this misunderstanding.  The error message
can point to a help file which may help them understand the issue,
If the implementation accepts the erroneous problem, instead people
get incorrect results, which is a lot harder to understand and track down.
They will waste more time.  Worse (from an implementor's point of view)
when they ask for help, the problem is less likely to be obvious
to figure out than if they ask about a compile-time error message.

MOTIVATION 2 (everybody):

Even experienced XQuery users write bugs, and sometimes use the wrong
variable name.  I have certainly written a loop with an index variable
that matches a name used in an outer loop.  That is a recipe for
hard-to-find bugs, so Java wisely added a rule to prohibit such
redefinition.

COUNTER-ARGUMENT: Avoid arbitrary restrictions

Lexical scoping has been used in many languages that allow
redefinition.  It's easy to understand and consistent. Somebody said
we don't improve software/languages by adding features, but by
removing unneeded restrictions - and here I'm arguing for adding an
unnecessary restriction.

Perhaps prohibiting redefinition makes XQuery slightly less "elegant"
in some abstract sense.  However, "elegance" is a secondary goal.  If
there is no known valid use case for a feature, and it is known that
programs using it are actually misunderstandings or "think-o"s, and
that such errors are fairly common, then the feature should go,
elegance or not.

Compare the rule (2.2.3.1 "Static Analysis phase") "if ... the static
type assigned to an expression other than () or data(()) is empty(), a
static error is raised."  This is clearly an arbitrary restriction,
and the language is simpler and more elegant without this restriction.
However, this is a case where XQuery has decided it is more useful to
to catch at compile-time certain otherwise hard-to-detect errors.

COUNTER-ARGUMENT:  Formal semantics

The formal semantics does make use of redefined variables.  For
example, the definitions of path expressions make use of fs:dot, and
it's difficult to come up with an alternative.  However, there is no
inherent reason why the core language must be a strict sub-language of
the surface language: The prohibition of redefinitions can be done at
or before the rewriting stage, allowing redefinitions in the core
language.  Alternatively, if you want the core language to be a strict
sub-language of the surface language, we can specify that the rule
against redefinition does not apply to a QName in the fake fn:
namespace.

IMPLEMENTATION

I have implemented this prohibition as a warning in my implementation.
It was not difficult to do so.  I suspect other implementors will do
the same. I would prefer to change the warning into an error, so I can
catch this mistake even when warnings are ignored or not shown to the
programmer.

For a related comment in the context of XSLT.see:
http://lists.w3.org/Archives/Public/public-qt-comments/2004Feb/0111.html

-- 
	--Per Bothner
per@bothner.com   http://per.bothner.com/

Received on Wednesday, 11 August 2004 21:27:24 UTC