Una buena manera de pensar en ello es "he cambiado nada, que cualquier código más tarde (incluyendo la ejecución de esta misma función otra vez más adelante) podría posiblemente nunca ver aparte el valor I estoy volviendo? " Si es así, eso es un efecto secundario. Si no, entonces puedes saber que no hay uno.
Por lo tanto, algo así como:
let inc_nosf v = v+1
no tiene efectos secundarios, ya que sólo devuelve un nuevo valor que es uno más que un entero v Así que si ejecuta el siguiente código en el nivel superior ocaml, que se obtiene. los resultados correspondientes:
# let x = 5;;
val x : int = 5
# inc_nosf x;;
- : int = 6
# x;;
- : int = 5
Como puede ver, el valor de x no cambió. Entonces, dado que no guardamos el valor de retorno, entonces nada realmente se incrementó. Nuestra función en sí misma solo modifica el valor de retorno, no x mismo. Así que para guardarlo en x, que tendríamos que hacer:
# let x = inc_nosf x;;
val x : int = 6
# x;;
- : int = 6
Dado que la función inc_nosf no tiene efectos secundarios (es decir, que sólo se comunica con el mundo exterior a través de su valor de retorno, no haciendo cualquier otra cambios).
Pero algo como:
let inc_sf r = r := !r+1
tiene efectos secundarios, ya que cambia el valor almacenado en la referencia representada por r. Así que si se ejecuta un código similar en el nivel superior, se obtiene esto, en lugar:
# let y = ref 5;;
val y : int ref = {contents = 5}
# inc_sf y;;
- : unit =()
# y;;
- : int ref = {contents = 6}
Por lo tanto, en este caso, a pesar de que todavía no guarda el valor de retorno, se puso incrementa de todos modos. Eso significa que debe haber habido cambios en algo que no sea el valor de retorno. En este caso, ese cambio fue la asignación usando :=
que cambió el valor almacenado de la ref.
Como regla general, en Ocaml, si evita usar referencias, registros, clases, cadenas, matrices y tablas hash, entonces evitará cualquier riesgo de efectos secundarios. Aunque puede usar literales de cadenas de forma segura, siempre que evite modificar la cadena en su lugar mediante funciones como String.set o String.fill. Básicamente, cualquier función que pueda modificar un tipo de datos en su lugar causará un efecto secundario.
Una sugerencia para el estilo: el patrón "if expression then true else false" u otros patrones similares son muy comunes entre los principiantes. Si lo piensas, para que la parte if sea elegida, la expresión tiene que ser verdadera y para la parte else tiene que ser falsa. Entonces este patrón se puede soltar y reducir a "expresión". – LiKao
¿Podría mostrar el código para eso? Definitivamente soy un principiante y podría usar alguna orientación. –
Claro, es bastante simple: En lugar de "si List.exists ((=) 7) myList then true else false ;;" simplemente podría escribir "List.exists ((=) 7) myList ;;". Si se detiene a pensar en los motivos, por qué estas dos afirmaciones tienen la misma semántica, aprenderá mucho sobre programación funcional (y también general). – LiKao