Skip to main content

Funciones lambda en Scala

⏱ Dedicación recomendada: 0 minutos
Esto considera el contenido visible y relevante, e ignora texto colapsado o marcado como opcional.


r8vnhill/scala-dibs

Una función lambda en Scala es una función anónima que puede ser tratada como un valor: asignada a una variable, pasada como argumento o devuelta desde otra función. La sintaxis general de una función lambda en Scala es:

(argumentos) => cuerpo
val add = (x: Int, y: Int) => x + y
val add2 = add(2, _)

Lambdas en Scala con funciones de orden superior

Al igual que en Kotlin, las lambdas en Scala se utilizan comúnmente con funciones de orden superior.

Por ejemplo, usando filter en una lista:

val numbers = List(1, 2, 3, 4, 5)
val evenNumbers = numbers.filter(_ % 2 == 0)

Aplicando lambdas en funciones de orden superior

Puedes crear tus propias funciones de orden superior que acepten lambdas como parámetros:

private def processInts(a: Int, b: Int, operation: (Int, Int) => Int): Int =
operation(a, b)
val sum = processInts(3, 4, _ + _)
¿Qué acabamos de hacer?
  • La función processInts acepta dos enteros y una lambda que define cómo operarlos.
  • Al llamar a processInts, proporcionamos una lambda que suma los dos números.

Desestructuración en lambdas

Scala permite desestructurar los parámetros de una lambda utilizando pattern matching directamente en la definición de la función anónima.

Ejemplo de desestructuración

val pairs = List((1, 2), (3, 4), (5, 6))
val sums = pairs.map { (x, y) => x + y }
¿Qué acabamos de hacer?
  • En este ejemplo, (x, y) desestructura cada tupla en sus componentes x e y.
  • La función lambda suma los componentes desestructurados.

Scala permite desestructurar estructuras anidadas:

val nestedPairs = List((1, (2, 3)), (4, (5, 6)))
val sums = nestedPairs.map { case (x, (y, z)) => x + y + z }
¿Qué acabamos de hacer?

Usamos case (x, (y, z)) para desestructurar cada tupla anidada en sus componentes x, y y z.

Este nivel de desestructuración no es directamente posible en Kotlin dentro de lambdas.

Características adicionales de Scala en lambdas

Currificación y aplicación parcial

Scala soporta la currificación, permitiendo definir funciones que se pueden aplicar parcialmente:

def sumar(a: Int)(b: Int): Int = a + b
val sumarCinco = sumar(5) _
println(sumarCinco(10)) // Output: 15

Esto facilita la creación de funciones a partir de otras, fijando algunos parámetros.

Funciones de múltiples parámetros y listas de parámetros

Scala permite definir funciones con múltiples listas de parámetros:

def funcion(a: Int)(b: Int)(c: Int): Int = a + b + c

Esto es útil para currificación y para manejar parámetros implicitos (contextuales).

Tipos de función avanzados

Scala tiene un sistema de tipos más potente que Kotlin en cuanto a funciones:

  • Funciones polimórficas: Puedes definir funciones que operan sobre tipos genéricos con más flexibilidad.
  • Tipos de función de orden superior: Permite tipos de funciones que aceptan o devuelven otras funciones con tipos genéricos.

Diferencias entre Scala 2 y Scala 3

Scala 3 introduce varias mejoras en las lambdas:

  • Inferencia de tipos mejorada: Permite omitir tipos en más lugares.
  • Sintaxis más concisa: Se simplifica la escritura de lambdas y tipos.
  • Funciones anónimas con múltiples parámetros: Se mejora la sintaxis para lambdas con varios parámetros.

Ejemplo de mejora en Scala 3

Scala 2:

val combinar: (Int, Int) => Int = (a: Int, b: Int) => a + b

Scala 3:

val combinar: (Int, Int) => Int = _ + _

En Scala 3, podemos usar _ + _ para indicar una función que suma dos parámetros.

Comparación con Kotlin

CaracterísticaScalaKotlin
Desestructuración en lambdasSoporta desestructuración completa, incluyendo anidadaSoporta desestructuración limitada, no en estructuras anidadas
Placeholder en lambdasPermite usar _ para parámetros anónimos en lambdasPermite usar it para referirse al único parámetro en lambdas
Currificación y múltiples listas de parámetrosSoporta currificación y funciones con múltiples parámetrosNo soportado directamente
Inferencia de tipos en lambdasInferencia más avanzada, especialmente en Scala 3Buena inferencia, pero menos flexible que Scala
Pattern matching en lambdasSoporta pattern matching completo en parámetros de lambdasLimitado a desestructuración simple
Sistema de tipos de funcionesMás expresivo y potente, con tipos de orden superiorMenos avanzado en este aspecto
Funciones de contextoSoportadas en Scala 3 (using clauses)Soportadas mediante receptores de contexto (context receivers) en versiones recientes

Ventajas de Scala respecto a Kotlin en lambdas

Beneficios

  • Mayor flexibilidad en desestructuración: Scala permite desestructurar parámetros en lambdas de forma más potente, incluyendo patrones anidados y pattern matching completo.
  • Sintaxis más concisa con placeholders: El uso de _ permite escribir lambdas de manera más compacta, pero el abuso de esta característica puede afectar la legibilidad.
  • Currificación nativa: Scala soporta currificación dentro de la firma de las funciones, lo que facilita la composición de funciones y la aplicación parcial.
  • Sistema de tipos más avanzado: Permite expresar tipos de funciones más complejos y polimórficos.
  • Pattern matching en lambdas: Scala permite usar pattern matching directamente en los parámetros de las lambdas, ofreciendo mayor expresividad.

Conclusión

Scala ofrece un conjunto de características avanzadas para trabajar con funciones lambda, proporcionando mayor flexibilidad y expresividad en comparación con Kotlin. Las mejoras introducidas en Scala 3 refuerzan estas capacidades, simplificando la sintaxis y ampliando la inferencia de tipos.

Mientras que Kotlin es conocido por su simplicidad y facilidad de uso, Scala se destaca por su poderoso sistema de tipos y sus características funcionales avanzadas, lo que lo convierte en una opción preferida para aquellos que buscan un mayor nivel de abstracción y funcionalidad en su código.