Exit e-book
Show all chapters
02
Programación funcional 101
02. 
Programación funcional 101

Sign up to our Newsletter

Signing up to our newsletter allows you to read all our ebooks.

    Introducción a la Programación con Efectos Funcionales usando ZIO
    02

    Programación funcional 101

    ¿Qué es la programación funcional?

    La programación funcional es un paradigma de programación, donde los programas son una composición de funciones puras. Esto representa una diferencia fundamental con la programación orientada a objetos, donde los programas son secuencias de instrucciones, que usualmente operan sobre algún estado mutable. Dichos programas son organizados usando funciones también, pero éstas no son funciones en el sentido matemático, porque no cumplen con algunas características fundamentales.

    Una función pura debe ser total

    Primeramente, una función debe ser total, esto significa que para cada entrada que se provea a la función debe haber una salida definida. Por ejemplo, la siguiente función para dividir dos enteros no es total:

    
    def divide(a: Int, b: Int): Int = a / b
    

    Para responder a la pregunta: ¿por qué esta función no es total? consideremos qué pasa si tratamos de dividir por cero:

    
    divide(5, 0)
    
    
    // java.lang.ArithmeticException: / by zero
    
    

    La división por cero no está definida y Java maneja esto lanzando una excepción. Eso significa que la función divide no es total porque no retorna ninguna salida en el caso donde b = 0.

     

    Algunas cosas importantes que podemos resaltar aquí:

     

    • Si miramos el encabezado de esta función, podemos darnos cuenta de que dice una mentira: que para cada par de enteros a y b, esta función siempre retornará otro entero, lo cual ya hemos visto que no es cierto para todos los casos.
    • Esto significa que cada vez que llamemos a la función divide en alguna parte de nuestra aplicación tendremos que ser muy cuidadosos, dado que nunca podemos estar completamente seguros de que la función vaya a retornar un entero.
    • Si nos olvidamos de considerar el caso excepcional cuando llamemos a divide, al momento de ejecutar nuestra aplicación ésta lanzará excepciones y dejará de trabajar como debería. Desafortunadamente, el compilador nada podrá hacer para ayudarnos a evitar este tipo de situación, el código compilará y recién veremos los problemas en tiempo de ejecución.

    Entonces, ¿cómo podemos solucionar este problema? Observemos esta definición alternativa de la función divide:

    
    def divide(a: Int, b: Int): Option[Int] =
      if (b != 0) Some(a/b) else None
    
    
    
    

    En este caso, la función divide retorna Option[Int] en vez de Int, de tal manera que cuando b = 0, la función retorna None en vez de lanzar una excepción. Así es como hemos transformado una función parcial en una función total, y gracias a esto tenemos algunos beneficios:

    • El encabezado de la función claramente comunica que algunas entradas no son manejadas porque retorna un Option[Int].
    • Cuando llamemos a la función divide en alguna parte de nuestra aplicación, el compilador nos obligará a considerar el caso en el que el resultado no está definido. Si no lo hacemos, habrá errores de compilación, eso significa que el compilador nos podrá ayudar a evitar muchos bugs en tiempo de compilación y que no aparecerán en tiempo de ejecución.
    PREVIOUS
    Chapter
    01
    NEXT
    Chapter
    03