Introducción a la programación funcional con Scala

Abinov Vishen | 23 de marzo, 2021

En informática, la programación funcional es un paradigma de programación en el que los programas se construyen aplicando y componiendo funciones. En este artículo, explicamos lo que hace que Scala sea único como lenguaje de programación y por qué es ideal para las aplicaciones actuales altamente escalables y centradas en los datos.

Por qué es importante la programación funcional

El software bien estructurado es fácil de escribir, fácil de depurar y proporciona una colección de módulos que pueden reutilizarse para reducir los costes de programación en el futuro. En su documento “Why Functional Programming Matters” (Por qué la programación funcional es importante), John Hughes señala que los problemas que resolvemos con el software son cada vez más complejos con el paso del tiempo. Se requiere una forma más práctica de probarlos y un enfoque más eficiente para escribirlos. El paradigma de la programación funcional ayuda mucho en estos dos aspectos.

Y lo que es más importante, este paradigma es natural para el paralelismo. Desde hace varios años, los avances en la velocidad bruta de la unidad central de procesamiento (CPU) han sido modestos. Sin embargo, los sistemas se han hecho más rápidos añadiendo más núcleos que funcionan en paralelo.

¿Por qué Scala?

Aunque existen múltiples lenguajes multiparadigma, Scala combina la programación orientada a objetos y la funcional en un lenguaje conciso. Hoy en día, es uno de los lenguajes más utilizados por la comunidad funcional, a la altura de F#, Haskell y Clojure, entre otros.

En Encora, somos grandes fanáticos de la Programación Funcional y de Scala por las siguientes razones:

El lenguaje es versátil y la combinación de características permite escribir programas concisos, elegantes y más fáciles de depurar y mantener que muchos otros lenguajes de programación.

Scala se ejecuta en una máquina virtual Java (JVM), y proporciona interoperabilidad y compatibilidad con Java, Groovy, Clojure, etc. Esto permite a los desarrolladores mantener sus bibliotecas y aprovechar las ventajas de la JVM.

Scala es más fácil de depurar y mantener que muchos otros lenguajes de programación, su mantenimiento es simplemente mucho más rápido.

En los últimos años, un número cada vez mayor de empresas se ha pasado a la programación funcional y a Scala, entre las que se encuentran gigantes tecnológicos como Twitter y LinkedIn. En 2020, Scala entró en el top 10 de los lenguajes que los desarrolladores quieren aprender, lo que demuestra aún más su popularidad.

Funciones puras

Una función pura depende únicamente de sus parámetros de entrada y solo debe devolver un resultado específico sin mutar una condición externa a su alcance. Un buen ejemplo de función pura se basa simplemente en el parámetro que recibe y ofrece un resultado.


def sin(value: Double): Double

Funciones no puras

Las funciones no puras permiten la modificación del contexto externo/interno. Las funciones puras son fáciles de probar y predecir. Sin embargo, a veces es necesario hacer algo que modifique el estado, como escribir un archivo o actualizar una tabla dentro de una base de datos. Por eso existen las funciones no puras. Por ejemplo,


def writeTofile(fileNameL String, text: String): Unit
def insertToDB(user: User): User

Funciones de alto orden

Uno de los rasgos más potentes de la programación funcional son las funciones de alto orden. Pueden tomar valores o funciones y devolver otros valores o funciones;

  • tomar una función, devolver un valor
  • tomar un valor, devolver una función
  • tomar una función, devolver una función

class List[T]{
	// This Function takes another Function called "fn" as a parameter
    // that it's applied to each of the elements within the List
    // and filters then if "fn" returns false for that element.
    def filter[T](fn: T => Boolean): List[T]
}

val list: List[Int] = // ... initialized with [1, 2, 3, 4, 5, 6, 7, 8, 9]
var odds: List[Int] = list.filter(v => v % 2 != 0)
// returns: [1, 3, 5, 7, 9]

Estas funciones no solo acortan los programas, sino que también ayudan a producir un código más limpio.


def isOdd(valor: Int): Boolean = {
	valor % 2 != 0
}

// let's define how we're going to filter
// this list using isOdd Function
val odds: List[Int] = list.filter(v = isOdd(v))
// returns: [1, 3, 5, 7, 9]

Inmutabilidad

La inmutabilidad se refiere a los datos de un objeto que no puede ser modificado una vez creado. En la programación funcional, no cambiamos los objetos en nuestras funciones, los pasamos a otras funciones para que sean manipulados. La inmutabilidad ayuda a preservar la capacidad de componer cosas.

Por supuesto, no siempre es posible utilizar estados inmutables, pero diseñar los programas con base en esta premisa es siempre muy recomendable.

Estos ejemplos contrastan las ventajas que ofrece Scala frente a un lenguaje orientado a objetos como Java,


// Java
// ... imports
public class Car {

	private final String _color;
    private final String _model;
    private final String _bran;
    private final Date _year;
    
    public Car(String color, String model, String brand, Date year) {
    	_color = color;
        _model = model;
        _brand = brand;
        _year = year;
    }
    
    public string getColor() {
    	return _color;
    }
    
    public String getModel() {
    	return _model;
    }
    
    public String getBrand() {
    	return _brand;
    }
    
    public Date getYear() {
    	return _year;
    }
}

// Scala

case class Car(color: String model: String brand: String year: Date)

Monads en Scala

Una monad es una interfaz que simplemente especifica una forma de composición de datos. Una mónada debe regirse por ciertas leyes. Scala no es tan estricto con estas leyes, y su enfoque es más práctico que nada.

Desde el punto de vista del lenguaje, los únicos rasgos que debe tener una mónada son las funciones de alto orden flatMap y map. Estos proporcionan la herramienta para componer los datos que contienen, mediante la aplicación de una función. El siguiente ejemplo lo explica mejor:


class Monad[A](value: A) {
	//receives a Function 'f' that transforms any 'A' value into 'B' value
    def map[B](f: A=> B): Monad[B] = new Monad(f(value))
    
    //receives a Function 'f' that transforms any 'A' value into another 'Monad[B]'
    def flatMap[B](f: A => Monad[B] = f(value)
}

val firstMonad = new Monad(4)
val secondMonad = new Monad(6)

val resultingMonad = firstMonad.flatMap { x => 
	secondMonad.map { y => 
    	y + x
    }
}

// returns: Modan[Int] = 10

Imagina que cada colección que conocemos es una Monad (en términos de Scala). Esto significaría que podemos componer los datos internos de esta colección al aplicar simplemente una función a través de map o flatMap.


def x2(value: Int): Int = {
	value * 2
}

val lista = Seq( 1, 2, 4, 5, 6, 7, 8, 9, /*...*/ 100, 101 )
var listaX2 = lista.map { v => x2(v) }
// results: Seq( 2, 4, 8, 10, 12, 14, 16, 18, /*...*/ 200, 202 )

Puntos clave para tener en cuenta

  • A medida que el software se vuelve más complejo, se necesitan métodos de desarrollo y mantenimiento más sofisticados para establecer la estructura y garantizar la calidad.
  • Scala es un lenguaje que cuenta con un soporte completo de la programación funcional así como del paradigma orientado a objetos, lo que lo convierte en uno de los lenguajes más utilizados por la comunidad funcional.
  • La combinación de características de Scala permite escribir programas concisos, elegantes y más fáciles de depurar y mantener que la mayoría de los demás lenguajes de programación.
  • Algunos de los aspectos más importantes de la programación funcional con Scala son las funciones puras, las funciones no puras, las funciones de alto orden, la inmutabilidad y las mónadas.

Acerca de Encora

Encora es líder en el amplio y creciente mercado de la externalización del desarrollo de productos. Creamos una ventaja competitiva a través de la aceleración de la innovación tecnológica al proporcionar a las empresas las herramientas, el talento y los procesos necesarios. Nuestros equipos de desarrollo tienen experiencia con la programación funcional y saben cómo resolver problemas de negocio utilizando Scala. No dude en ponerse en contacto con nosotros si tiene alguna pregunta, o si quiere hablar de las necesidades de su empresa.

Contáctenos

Contenido

Compartir Artículo

Artículos Destacados