La forma "normal" de expresar lo que es una función pura es en términos de transparencia referencial . Una función es pura si es referencialmente transparente .
Transparencia referencial , aproximadamente, significa que puede reemplazar la llamada a la función con su valor de retorno o viceversa en cualquier punto del programa, sin cambiar el significado del programa.
Entonces, por ejemplo, si C's printf
fueran referencialmente transparentes, estos dos programas deberían tener el mismo significado:
printf("Hello");
y
5;
y todos los siguientes programas deben tener el mismo significado:
5 + 5;
printf("Hello") + 5;
printf("Hello") + printf("Hello");
Porque printf
devuelve el número de caracteres escritos, en este caso 5.
Se vuelve aún más obvio con las void
funciones. Si tengo una función void foo
, entonces
foo(bar, baz, quux);
debería ser lo mismo que
;
Es decir, dado que foo
no devuelve nada, debería poder reemplazarlo con nada sin cambiar el significado del programa.
Está claro, entonces, que ni printf
ni foo
son referencialmente transparentes, por lo que ninguno de ellos es puro. De hecho, una void
función nunca puede ser referencialmente transparente, a menos que no sea una operación.
Encuentro esta definición mucho más fácil de manejar que la que usted dio. También le permite aplicarlo en la granularidad que desee: puede aplicarlo a expresiones individuales, a funciones, a programas completos. Te permite, por ejemplo, hablar de una función como esta:
func fib(n):
return memo[n] if memo.has_key?(n)
return 1 if n <= 1
return memo[n] = fib(n-1) + fib(n-2)
Podemos analizar las expresiones que componen la función y concluir fácilmente que no son referencialmente transparentes y, por lo tanto, no son puras, ya que utilizan una estructura de datos mutable, es decir, la memo
matriz. Sin embargo, también podemos mirar la función y podemos ver que es referencialmente transparente y, por lo tanto, pura. A esto a veces se le llama pureza externa , es decir, una función que parece pura para el mundo exterior, pero que se implementa como impura internamente.
Estas funciones siguen siendo útiles, porque mientras la impureza infecta todo lo que la rodea, la interfaz pura externa construye una especie de "barrera de pureza", donde la impureza solo infecta las tres líneas de la función, pero no se filtra al resto del programa. . Estas tres líneas son mucho más fáciles de analizar para determinar si son correctas que el programa completo.