Introducción
En este módulo, exploraremos las funciones de orden superior y los conceptos de programación funcional en Kotlin. Las funciones de orden superior son funciones que pueden tomar otras funciones como parámetros o devolverlas como resultado. La programación funcional es un paradigma que trata la computación como la evaluación de funciones matemáticas y evita el estado mutable y los efectos secundarios.
Conceptos Clave
Funciones de Orden Superior
- Definición: Una función de orden superior es una función que puede tomar otra función como parámetro o devolver una función.
 - Sintaxis: En Kotlin, las funciones de orden superior se definen de manera similar a las funciones regulares, pero con parámetros de tipo función.
 
Programación Funcional
- Inmutabilidad: En la programación funcional, los datos son inmutables, lo que significa que no se pueden cambiar una vez creados.
 - Funciones Puras: Una función pura es una función que siempre produce el mismo resultado dado el mismo conjunto de entradas y no tiene efectos secundarios.
 - Expresiones Lambda: Las lambdas son funciones anónimas que se pueden tratar como valores y pasar como argumentos a las funciones de orden superior.
 
Ejemplos Prácticos
Funciones de Orden Superior
Ejemplo 1: Función que toma otra función como parámetro
fun <T> List<T>.customFilter(predicate: (T) -> Boolean): List<T> {
    val result = mutableListOf<T>()
    for (item in this) {
        if (predicate(item)) {
            result.add(item)
        }
    }
    return result
}
fun main() {
    val numbers = listOf(1, 2, 3, 4, 5, 6)
    val evenNumbers = numbers.customFilter { it % 2 == 0 }
    println(evenNumbers) // Output: [2, 4, 6]
}Explicación:
customFilteres una función de orden superior que toma una funciónpredicatecomo parámetro.predicatees una función que toma un elemento de tipoTy devuelve unBoolean.customFilterfiltra los elementos de la lista según elpredicateproporcionado.
Ejemplo 2: Función que devuelve otra función
fun createMultiplier(factor: Int): (Int) -> Int {
    return { number -> number * factor }
}
fun main() {
    val multiplier = createMultiplier(3)
    println(multiplier(5)) // Output: 15
}Explicación:
createMultiplieres una función que devuelve una función lambda.- La función lambda toma un 
numbery lo multiplica porfactor. 
Programación Funcional
Ejemplo 3: Uso de Lambdas y Funciones Puras
val square: (Int) -> Int = { number -> number * number }
fun main() {
    val numbers = listOf(1, 2, 3, 4, 5)
    val squaredNumbers = numbers.map(square)
    println(squaredNumbers) // Output: [1, 4, 9, 16, 25]
}Explicación:
squarees una lambda que toma unInty devuelve su cuadrado.mapes una función de orden superior que aplica la funciónsquarea cada elemento de la lista.
Ejercicios Prácticos
Ejercicio 1: Filtrar Números Impares
Escribe una función de orden superior llamada filterOddNumbers que tome una lista de enteros y una función predicate como parámetros, y devuelva una lista de números impares.
fun filterOddNumbers(numbers: List<Int>, predicate: (Int) -> Boolean): List<Int> {
    // Tu código aquí
}
fun main() {
    val numbers = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
    val oddNumbers = filterOddNumbers(numbers) { it % 2 != 0 }
    println(oddNumbers) // Output esperado: [1, 3, 5, 7, 9]
}Solución:
fun filterOddNumbers(numbers: List<Int>, predicate: (Int) -> Boolean): List<Int> {
    val result = mutableListOf<Int>()
    for (number in numbers) {
        if (predicate(number)) {
            result.add(number)
        }
    }
    return result
}
fun main() {
    val numbers = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
    val oddNumbers = filterOddNumbers(numbers) { it % 2 != 0 }
    println(oddNumbers) // Output: [1, 3, 5, 7, 9]
}Ejercicio 2: Crear una Función de Orden Superior para Transformar Strings
Escribe una función de orden superior llamada transformStrings que tome una lista de strings y una función transform como parámetros, y devuelva una lista de strings transformados.
fun transformStrings(strings: List<String>, transform: (String) -> String): List<String> {
    // Tu código aquí
}
fun main() {
    val strings = listOf("kotlin", "is", "awesome")
    val uppercasedStrings = transformStrings(strings) { it.uppercase() }
    println(uppercasedStrings) // Output esperado: ["KOTLIN", "IS", "AWESOME"]
}Solución:
fun transformStrings(strings: List<String>, transform: (String) -> String): List<String> {
    val result = mutableListOf<String>()
    for (string in strings) {
        result.add(transform(string))
    }
    return result
}
fun main() {
    val strings = listOf("kotlin", "is", "awesome")
    val uppercasedStrings = transformStrings(strings) { it.uppercase() }
    println(uppercasedStrings) // Output: ["KOTLIN", "IS", "AWESOME"]
}Conclusión
En esta sección, hemos aprendido sobre las funciones de orden superior y la programación funcional en Kotlin. Hemos visto cómo las funciones pueden tomar otras funciones como parámetros y devolver funciones, y cómo las lambdas y las funciones puras son fundamentales en la programación funcional. Los ejercicios prácticos proporcionados te ayudarán a reforzar estos conceptos y a aplicarlos en tus propios proyectos.
En el próximo módulo, exploraremos las corrutinas y la programación asíncrona en Kotlin, lo que te permitirá escribir código más eficiente y manejable para operaciones concurrentes.
Curso de Programación en Kotlin
Módulo 1: Introducción a Kotlin
- Introducción a Kotlin
 - Configuración del Entorno de Desarrollo
 - Conceptos Básicos de Kotlin: Variables y Tipos de Datos
 - Flujo de Control: Condicionales y Bucles
 - Funciones y Lambdas
 
Módulo 2: Programación Orientada a Objetos en Kotlin
- Clases y Objetos
 - Herencia e Interfaces
 - Modificadores de Visibilidad
 - Clases de Datos y Clases Selladas
 - Declaraciones de Objetos y Objetos Compañeros
 
Módulo 3: Características Avanzadas de Kotlin
- Colecciones y Genéricos
 - Funciones de Extensión
 - Funciones de Orden Superior y Programación Funcional
 - Corrutinas y Programación Asíncrona
 - DSL (Lenguaje Específico de Dominio) en Kotlin
 
Módulo 4: Kotlin para Desarrollo Android
- Introducción al Desarrollo Android con Kotlin
 - Construcción de Interfaces de Usuario
 - Manejo de Entrada del Usuario
 - Redes y Almacenamiento de Datos
 - Pruebas y Depuración
 
