Menú de navegaciónMenú
Categorías

La mejor forma de Aprender Programación online y en español www.campusmvp.es

?id=9cb0397b-fb70-4f67-b322-fd08d19c486d

Programación funcional: Inmutabilidad y funciones puras

Anteriormente en este blog ya hemos hablado de programación funcional, concretamente sobre currificación y pattern matching. En esta ocasión estudiaremos un par de conceptos adicionales de la programación funcional y veremos cómo se pueden aplicar a la programación cotidiana.

Inmutabilidad de objetos

La inmutabilidad es la propiedad que tiene un objeto que no puede cambiar su estado. Como consecuencia, la inmutabilidad aporta muchas facilidades a la hora de razonar sobre nuestro código, ya que nos libera de pensar en los cambios sufridos por objetos a lo largo del programa. Además, los objetos inmutables son automáticamente seguros en hilos (o thread-safe), ya que pueden ser accedidos de manera concurrente sin consecuencias, al no poder modificarse.


Foto: "Inmutable" de dominio público.

En programación orientada a objetos generalmente asumimos que el estado de un objeto puede cambiar según los métodos que se llamen sobre el mismo. Sin embargo, en ocasiones podemos construir clases que den lugar a objetos inmutables. Aunque a priori esto pueda parecer poco útil, veamos algunos ejemplos de lo que se puede hacer aprovechando la inmutabilidad. En Java, por ejemplo, la clase String es inmutable:

String saludo = new String("¡Hola campusMVP!");

// no modifica la cadena:
saludo.replaceAll("Hola", "Buenas");

Aunque podríamos esperar que la cadena ahora contuviese "¡Buenas campusMVP!", no es así, sino que el método ha devuelto una nueva cadena:

saludo = saludo.replaceAll("Hola", "Buenas");

Ahora la cadena referenciada por la variable saludo sí contiene el resultado esperado, pero en un objeto distinto al inicial.

Nota: dadas sus ventajas, la inmutabilidad de las cadenas de texto es algo que comparten muchos lenguajes de programación y que no es exclusivo de Java. También lo son en C#, C++, Perl, Python... ¡Incluso JavaScript!

En Java podemos crear nuestras propias clases inmutables con la palabra clave final, que evita que haya clases descendientes, y usando métodos que no cambien el estado de los datos miembro. Por ejemplo:

public final class Person {
  private final String name;
  private final int age;

  // ...
}

En otros lenguajes, la inmutabilidad es una característica clave diferenciadora. Por ejemplo, R, un popular lenguaje orientado a análisis estadístico, es conocido por su extenso uso de la inmutabilidad, sin ser puramente funcional. En Rust, todas las variables son por defecto inmutables. La mayoría de lenguajes funcionales incorporan inmutabilidad y ausencia de variables, de forma que un identificador sólo puede hacer referencia a un valor y ese valor no se puede modificar.

En cualquier caso, la idea de usar objetos inmutables puede ser útil en diversos contextos, para proporcionar mayor seguridad y eficiencia así como facilidades para concurrencia sin necesidad de sincronización.

Funciones puras

Los lenguajes funcionales generalmente tratan de asegurar la transparencia referencial, es decir, que cualquier expresión del lenguaje se pueda sustituir por su valor sin que eso altere el comportamiento del programa. Para ello son necesarios objetos inmutables, pero también funciones que siempre devuelvan el mismo valor ante las mismas entradas.

Por ejemplo, consideremos una función que cuenta los caracteres de una entrada por pantalla, que se correspondería con el siguiente código Python:

def input_length():
  len(input())

¿Podemos asegurar que la llamada input_length() devolverá siempre el mismo valor? No, puesto que el usuario podría introducir distintas cadenas. Esto se debe a que la función accede a información externa a los parámetros que recibe.

Adicionalmente, una propiedad deseable sería que una función no modificase elementos fuera de su ámbito, es decir, no tuviese efectos secundarios, como pueden ser escribir a un archivo o modificar variables globales. Una vez que una función siempre devuelve las mismas salidas para las mismas entradas y no tiene efectos secundarios, se la denomina función pura.

Las funciones puras son útiles porque se pueden ejecutar desordenadamente y en paralelo, cuando no hay dependencias de parámetros entre ellas. Ejemplos de estas son cualquier función matemática y algoritmos deterministas. Son funciones impuras, por otro lado, los generadores de números aleatorios.

Espero que este artículo te haya ayudado a entender las ventajas de usar ideas provenientes de la programación funcional, y que las puedas aplicar en tu día a día de la programación.

Fuentes y más información:

David Charte David Charte es un ingeniero informático y matemático apasionado por la divulgación del conocimiento. Cuando no está tratando de aprender un nuevo lenguaje, investiga en el campo de la ciencia de datos. Puedes seguirlo en Twitter en @fdavidcl. Ver todos los posts de David Charte
Archivado en: Lenguajes y plataformas

¿Te vas a perder los mejores trucos de programación?

Únete a miles de desarrolladores que ya reciben cada mes nuestro boletí­n por email. No te pierdas los mejores trucos, noticias y frikadas.

Enviamos poco, pero bueno. Palabra de desarrollador.

Suscríbete aquí­

Sí­guenos también en:

Telegram LinkedIn YouTube
La mejor formación online para desarrolladores como tú

Agregar comentario

Los datos anteriores se utilizarán exclusivamente para permitirte hacer el comentario y, si lo seleccionas, notificarte de nuevos comentarios en este artículo, pero no se procesarán ni se utilizarán para ningún otro propósito. Lee nuestra política de privacidad.