2011-05-17 8 views
25

Tengo curiosidad por saber por qué la coma <,> es un atajo para and y no andalso en las pruebas de guardia.Cuándo preferir `y` sobre` andalso` en las pruebas de guardia

Como me llamaría un "nativo de C", no veo ninguna deficiencia en la evaluación booleana de cortocircuitos.

Recopilé código de prueba usando la bandera to_core para ver qué código realmente se genera. Usando la coma, veo el valor de la mano izquierda y el valor de la derecha y el valor se evalúan y se hacen las dos. Con andalso, tiene un bloque de mayúsculas y minúsculas dentro del bloque de mayúsculas y minúsculas sin llamar al erlang:and/2.

No realicé pruebas de referencia, pero me atrevo a decir que la variante andalso es la más rápida.

Respuesta

25

para ahondar en el pasado:

  • originalmente en guardias sólo había , separados pruebas que fueron evaluados de izquierda a derecha hasta que no había más y el guardia tuvieron éxito o una prueba falló y el guardia como un todo falló. Más tarde se agregó ; para permitir guardias alternativos en la misma cláusula. Si los guardias evalúan ambos lados de un , antes de la prueba, entonces alguien se equivocó en el camino. El ejemplo de @ Kay parece implicar que van de izquierda a derecha como deberían.

  • Los operadores booleanos solo fueron permitidos mucho más tarde en las guardias.

  • and, junto con or, xor y not, es un operador booleano y no estaba destinado para el control. Son todos strict y evalúan sus argumentos primero, como los operadores aritméticos +, -, * y '/'. También existen operadores booleanos estrictos en C.

  • El cortocircuito control de operadores andalso y orelse se añadieron más tarde para simplificar algo de código. Como ya dijiste, el compilador los expande a las expresiones anónimas case, por lo que no hay ganancia de rendimiento en su uso, solo la conveniencia y la claridad del código. Esto explicaría el código resultante que viste.

  • N.B. en guardias hay pruebas y no expresiones. Hay una diferencia sutil que significa que al usar and y andalso es equivalente a , usando orelse no es equivalente a ;. Esto queda en otra pregunta. Sugerencia: se trata de fracaso.

Así pues, tanto and y andalso tienen su lugar.

4

Es una razón histórica. and se implementó antes de andalso, que se introdujo en Erlang 5.1 (la única referencia que puedo encontrar ahora es EEP-17). Los guardias no se han cambiado debido a la compatibilidad con versiones anteriores.

7

Adam Lindbergs link tiene razón. Usar la coma genera mejor código de haz que usar andalso. He compilado el siguiente código usando la bandera to_asm +:

a(A,B) -> 
    case ok of 
     _ when A, B -> true; 
     _ -> false 
    end. 
aa(A,B) -> 
    case ok of 
     _ when A andalso B -> true; 
     _ -> false 
    end. 

que genera

{function, a, 2, 2}. 
    {label,1}. 
    {func_info,{atom,andAndAndalso},{atom,a},2}. 
    {label,2}. 
    {test,is_eq_exact,{f,3},[{x,0},{atom,true}]}. 
    {test,is_eq_exact,{f,3},[{x,1},{atom,true}]}. 
    {move,{atom,true},{x,0}}. 
    return. 
    {label,3}. 
    {move,{atom,false},{x,0}}. 
    return. 

{function, aa, 2, 5}. 
    {label,4}. 
    {func_info,{atom,andAndAndalso},{atom,aa},2}. 
    {label,5}. 
    {test,is_atom,{f,7},[{x,0}]}. 
    {select_val,{x,0},{f,7},{list,[{atom,true},{f,6},{atom,false},{f,9}]}}. 
    {label,6}. 
    {move,{x,1},{x,2}}. 
    {jump,{f,8}}. 
    {label,7}. 
    {move,{x,0},{x,2}}. 
    {label,8}. 
    {test,is_eq_exact,{f,9},[{x,2},{atom,true}]}. 
    {move,{atom,true},{x,0}}. 
    return. 
    {label,9}. 
    {move,{atom,false},{x,0}}. 
    return. 

Yo sólo miraba en lo que se genera con la bandera to_core +, pero es evidente que hay una etapa de optimización entre to_core y to_asm.

4

los operadores booleanos "y" y "o" Siempre me lo quitaron evalúan en ambos los lados del operador. Mientras que si desea la funcionalidad de los operadores C & & y || (donde el segundo argumento se evalúa solo si es necesario ... por ejemplo, si queremos evaluar "verdadero orelse falso" tan pronto como se descubra que es el primer argumento, no se evaluará el segundo argumento, que no es el caso tenía "o" usado) vaya para "y también" y "orelse".

Cuestiones relacionadas