2011-09-28 7 views
8

Para una asignación de tareas, se nos ha ordenado completar una tarea sin introducir ningún "efecto secundario". Busqué "efectos secundarios" en Wikipedia, y aunque entiendo que en teoría significa "modifica un estado o tiene una interacción observable con funciones de llamada", tengo problemas para descifrar detalles.OCaml: ¿El almacenamiento de algunos valores que se utilizarán más adelante introduce los "efectos secundarios"?

Por ejemplo, ¿la creación de un valor que tiene un resultado de tiempo de no compilación puede introducir efectos secundarios?

decir que he tenido (podría no ser sintácticamente perfecta):

val myList = (someFunction x y);; 
if List.exists ((=) 7) myList then true else false;; 

Sería esto introducir efectos secundarios? Supongo que tal vez estoy confundido sobre lo que significa "modificar un estado" en la definición de efectos secundarios.

+3

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

+0

¿Podría mostrar el código para eso? Definitivamente soy un principiante y podría usar alguna orientación. –

+0

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

Respuesta

8

No; un efecto secundario se refiere a, p. mutando una celda ref con el operador de asignación :=, u otras cosas donde el valor referido por un nombre cambia con el tiempo. En este caso, myList es un valor inmutable que nunca cambia durante el programa, por lo tanto está libre de efectos.

Ver también

http://en.wikipedia.org/wiki/Referential_transparency_(computer_science)

+0

Gracias, ese enlace es muy útil para una mejor comprensión de la programación funcional y los efectos secundarios. –

5

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.

Cuestiones relacionadas