xqueryxquery-3.1

Why does xquery allow local variable redeclaration?


This will not even raise a warning:

xquery version "3.1";
let $a := 1
let $a := 2
return $a
(: yields 2 in all runtimes I tested :)

Why would a (functional) programming language allow variable re-declarations? I really just want to get the rationale behind it. By rejecting this at the compile step would enable some more aggressive optimisations, I believe. Since local variables are also known to child scopes this just leaves more room for hard to catch errors. JavaScript had this for years with var and finally got rid of it by introducing let and const.

Here is an example where it might be hard to track values.

xquery version "3.1";
let $f := function ($c) {
  (: some code ... :)
  let $b := $a
  let $a := 2
  let $c := $b
  (: some more code ... :)
  return ($a, $b, $c)
}
let $a := 1
return ($a, $f($a), $a)

You might want to guess first, before evaluating it.


Solution

  • "Why" questions are always difficult, because you can guess why the designers might have made the decisions they did, but it's usually not possible to get historical evidence of their reasoning. If you want research the history, the archives of the working group are available at https://lists.w3.org/Archives/Public/public-xsl-query/ -- but the search facilities are not particularly good, so you'll have your work cut out. But even if you find the relevant discussion in the minutes, it will probably only record the decision, and not the detailed arguments.

    XSLT 1.0 didn't allow local variables to be re-declared, and I seem to recall that XSL people were generally against allowing it, while XQuery people were generally in favour. There are arguments both ways. The main argument for allowing it is probably the "no needless restrictions" argument: you don't disallow something if it has well-defined semantics. The argument for disallowing it was that people are likely to misuse and misunderstand it; they think that the two variables must somehow be related if they have the same name.

    The Javascript analogy isn't a particularly good one, because variables in a procedural language are rather different from variables in a functional language.

    Many other languages allow two local variables to have the same name provided they have different scope.