En respuesta a su primera pregunta acerca de las variables, y el segundo pregunta acerca de si las declaraciones.
No puede cambiar el valor de una variable (un nombre estúpido no lo es, dado que no varían).
El polvo de duende mágico para usar XQuery con cualquier lógica compleja (y algo así como variables mutables) es la recursión.
Robert Harvey mencionó el constructo del lenguaje del bucle for, en el cual la variable cambia cada vez, que es muy relevante, pero que no siempre puede resolver sus problemas a menos que su comportamiento intencionado se pueda lograr mediante la simple iteración de una lista . Lo que estabas pidiendo era variables mutables.
Con recursion sus funciones se llaman a sí mismas. Esto significa que pueden pasar un valor modificado a la siguiente invocación de función en lugar del valor que ya tienen. Más o menos se suma a una variable mutable, pero permite que permanezcan los beneficios de un lenguaje funcional.
Puede ser un poco arriesgado pasar de una forma de pensar procedimental (ejecución secuencial de pasos) a una forma de pensar funcional (evaluación simultánea de cláusulas).
La recursividad permite que las cláusulas que se evalúan realmente dependan de una lógica compleja que se ve secuencial. En la práctica, simplemente estás creando cláusulas que exigen que otros sean evaluados antes de que puedan evaluarse a sí mismos, lo cual no es exactamente lo mismo.
Aquí hay un ejemplo estúpido, completamente irrelevante y totalmente no probado que muestra cómo una lista puede ser modificada 'sobre la marcha' ya que es atravesada por recursión, algo que es imposible en un bucle for.
Tenga en cuenta que la variable $ patternsremaining es estrictamente una nueva variable (calculada en parte en función de $ patrones). Los patrones que se pasan como un argumento en la llamada recursiva se asignan a $ patrones dentro de la nueva invocación de función.
(: Here $patterns looks like <pattern match="something" replace="else" /> :)
declare function local:transform($text as text(), $patterns as element(pattern)*) {
if(not($patterns)) then
$text
else
let $patternsremaining := $patterns[position() > 1],
$modifiedtext := replace($text, $pattern/@match, $pattern/@replace)
return
if($local:language="French" and not($patterns[@match='le'])) then (
local:transform($modifiedtext, ($patternsremaining, <pattern match="Londres" replace="London" />))
)
else(
local:transform($modifiedtext, $patternsremaining)
)
};
Para las actividades del hardcore con XSLT y XQuery (por ejemplo, los compiladores de escritura) recursividad es el único modelo que he encontrado con suficiente potencia. Sin embargo, los ejemplos reales tienden a parecer incluso más complicados que el anterior.
En cuanto a la instrucción if() then() else(), porque es factible que el mismo contexto de ejecución (si es un codificador de procedimientos piense 'combinación de variables de pila') se haya encontrado antes, y la misma expresión ya se evaluó en otro lugar, entonces la declaración if NUNCA se evaluará nuevamente, porque el intérprete puede almacenar en caché el resultado, en función de la invocación anterior. Por lo tanto, no es estrictamente cierto que puede confiar en la secuencia. ¡No puede ejecutarse en absoluto!
Esto es posible porque está integrado en la definición del lenguaje que no puede haber efectos secundarios que puedan cambiar el resultado de una evaluación funcional (de ahí las variables que no varían).
Esta cacheabilidad es una característica central del enfoque funcional. Crea el potencial de escribir intérpretes altamente eficientes, pero requiere que piense de forma recursiva si desea poder operar con valores variables.
Tengo que agregar una pregunta a esto: ¿No debería ser posible actualizar una variable existente en una instrucción if porque en este caso el orden de ejecución es claro? ¿Supongo que no puedes usar algo como $ x = $ x + 1 en un bucle? –