Translate

domingo, 21 de abril de 2024

Guards en Erlang


Guards son cláusulas adicionales que pueden ir en la cabeza de una función para hacer pattern matching más expresivo. Como se mencionó anteriormente, el pattern matching es algo limitado ya que no puede expresar cosas como un rango de valores o ciertos tipos de datos. 

Por ejemplo, esto con Pattern matching : 

old_enough(0) -> false;

old_enough(1) -> false;

old_enough(2) -> false;

...

old_enough(14) -> false;

old_enough(15) -> false;

old_enough(_) -> true.


Es muy trabajoso pero si utilizamos guards : 


old_enough(X) when X >= 16 -> true;

old_enough(_) -> false.


Tenga en cuenta que Guards deben devolver verdadero para tener éxito. Guards fallará si devuelve falso o si genera una excepción. Supongamos que ahora prohibimos conducir a las personas mayores de 104 años. Nuestras edades válidas para conductores ahora son desde 16 años hasta 104 años. Tenemos que ocuparnos de eso, pero ¿cómo? Agreguemos una segunda cláusula de protección:


right_age(X) when X >= 16, X =< 104 -> true;

right_age(_)  -> false.


La coma (,) actúa de manera similar al operador and y el punto y coma (;) actúa un poco como or. Ambas expresiones deben tener éxito para que retorne verdadero. También podríamos representar la función al revés:


wrong_age(X) when X < 16; X > 104 -> true;

wrong_age(_) -> false.


Con punto y coma, si la primera condición falla, intenta con la segunda y luego con la siguiente, hasta que una tenga éxito o todas fallen.

Un punto negativo de los guards es que no aceptan funciones definidas por el usuario debido a los efectos secundarios. Erlang no es un lenguaje de programación puramente funcional (como lo es Haskell) porque depende mucho de los efectos secundarios: puedes realizar E/S, enviar mensajes entre actores o generar errores como quieras y cuando quieras. No existe una forma trivial de determinar si una función que usaría en una protección imprimiría o no texto o detectaría errores importantes cada vez que se prueba en muchas cláusulas de función. Entonces, en cambio, Erlang simplemente no confía en usted (¡y puede que sea correcto hacerlo!)