Fallo es el flujo de control en Verse.
A diferencia de otros lenguajes de programación que utilizan los valores booleanos verdadero y falso para cambiar el flujo de un programa, Verse utiliza expresiones que pueden tener éxito o fallar. Estas expresiones se denominan expresiones fallidas, y sólo pueden ejecutarse en un contexto de fallo.
El uso de fallos para el flujo de control significa que el trabajo no tiene que duplicarse, y que puede evitar errores sutiles.
Por ejemplo, en otros idiomas, hay que comprobar que un índice para una matriz es válido antes de acceder al elemento de la matriz en ese índice, lo cual es una causa común de errores en otros idiomas.
En Verse, la validación y el acceso se combinan para evitarlo.
Por ejemplo:
if (Element := MyArray[Index]):
Log(Element)
Expresión fallida
Una expresión fallida es una expresión que puede tener éxito y producir un valor, o fallar y no devolver ningún valor. Ejemplos de expresiones que fallan incluyen la indexación en una matriz porque un índice no válido fallará, y el uso de operadores como la comparación de dos valores.
El código que escribes no es falible predeterminado. Por ejemplo, para escribir una función que pueda fallar, debes añadir el efecto especificador <decides> a la definición de la función. Actualmente, también es necesario añadir <transacts> al usar <decides>.
Para obtener una lista completa de las expresiones que pueden fallar, consulta la lista de Expresiones en Verse.
Contexto de fallo
Un contexto de fallo es un contexto en el que se permite ejecutar expresiones con fallo. El contexto define lo que ocurre si la expresión falla. Cualquier error en un contexto de fallo provocará errores en todo el contexto.
Un contexto de error permite que las expresiones anidadas sean expresiones de error, como expresiones o argumentos de función en una expresión block.
Un aspecto útil de los contextos de fallo en Verse es que son una forma de ejecución especulativa, lo que significa que puedes probar acciones sin confirmar. Cuando una expresión tiene éxito, los efectos de la expresión se confirman, como cambiar el valor de una variable. Si la expresión falla, los efectos de la expresión se revierten, como si la expresión nunca hubiera ocurrido.
De esta manera, puedes ejecutar una serie de acciones que acumulen cambios, pero esas acciones se desharán si fallan en algún lugar.
Para que esto funcione, todas las funciones llamadas en el contexto de fallo deben tener el especificador de efecto <transacts>, y el compilador se quejará si no lo tienen.
Las funciones definidas por el usuario no tienen el efecto transacts predeterminado. Debe añadirse un especificador explícito <transacts> a sus definiciones. Algunas funciones nativas tampoco tienen el efecto transacts y no pueden ser llamadas en contextos de fallo.
Un ejemplo de función nativa sin <transacts> podría ser un componente_de_audio con un método BeginSound(). Si el sonido se pone en marcha, aunque se detenga podría haberse notado.
La siguiente lista incluye todos los contextos de fallo en Verse:
-
La condición en expresiones
if.if (test-arg-block) { … } -
Las expresiones de iteración y de filtro en las expresiones
for. Ten en cuenta quefores especial porque crea un contexto de fallo para cada iteración. Si las iteraciones están anidadas, entonces los contextos de fallo también estarán anidados. Cuando una expresión falla, el contexto de fallo más interno es abortado, y la iteración adjunta, si la hay, continúa con la siguiente iteración.for (Item : Collection, test-arg-block) { … } -
El cuerpo de una función o método que tiene el especificador de efecto
<decides>.IsEqual()<decides><transacts> : void = { … } -
El operando del operador
not.not expression -
El operando izquierdo para
or.expression1 or expression2 -
Inicializando una variable que tiene el tipo
option.option{expression}