← Scala EspañolChapter 05 of 13

Funciones

## Objetivos de Aprendizaje - Dominar definiciones de funciones con def - Comprender parametros de funciones y tipos de retorno - Aprender recursion - Trabajar con funciones anonimas - Comprender closures y aplicaciones parciales ## Basicos de Funciones ### Definiendo Funciones ```scala def greet(): String = { "Hello, World!" } println(greet()) // Hello, World! ``` ### Funcion con Parametros ```scala def add(a: Int, b: Int): Int = { a + b } println(add(3, 5)) // 8 ``` ### Inferencia del Tipo de Retorno Scala puede inferir tipos de retorno para expresiones: ```scala def add(a: Int, b: Int) = a + b // Tipo de retorno inferido como Int def greet() = "Hello" // Tipo de retorno inferido como String ``` ### Tipo de Retorno Unit ```scala def printSum(a: Int, b: Int): Unit = { println(s"Sum: ${a + b}") } printSum(3, 5) // Sum: 8 ``` ## Tipos de Parametros ### Parametros por Defecto ```scala def greet(name: String = "World") = s"Hello, $name!" greet() // Hello, World! greet("Alice") // Hello, Alice! ``` ### Argumentos Nombrados ```scala def connect(host: String = "localhost", port: Int = 8080) = { s"$host:$port" } connect(port = 9000, host = "server") // server:9000 ``` ### Argumentos Variables (Varargs) ```scala def sum(numbers: Int*): Int = { numbers.sum } sum(1, 2, 3, 4, 5) // 15 sum(1, 2, 3) // 6 ``` ### Grupos de Parametros ```scala def addAndMultiply(a: Int)(b: Int)(c: Int): Int = { (a + b) * c } addAndMultiply(1)(2)(3) // 9 ``` ## Recursion ### Recursion Basica ```scala def factorial(n: Int): BigInt = { if (n <= 1) 1 else n * factorial(n - 1) } factorial(5) // 120 ``` ### Recursion de Cola Las funciones tail-recursive se optimizan para evitar desbordamiento de pila: ```scala def factorialTail(n: Int): BigInt = { @annotation.tailrec def loop(acc: BigInt, n: Int): BigInt = { if (n <= 1) acc else loop(acc * n, n - 1) } loop(1, n) } factorialTail(10000) // Funciona sin desbordamiento de pila ``` ### Recursion Mutua ```scala def isEven(n: Int): Boolean = if (n == 0) true else isOdd(n - 1) def isOdd(n: Int): Boolean = if (n == 0) false else isEven(n - 1) isEven(10) // true ``` ## FuncionesAnonimas ### Sintaxis Basica ```scala val addOne = (x: Int) => x + 1 addOne(5) // 6 ``` ### Multiples Parametros ```scala val add = (a: Int, b: Int) => a + b add(3, 5) // 8 ``` ### Sin Parametros ```scala val getTime = () => System.currentTimeMillis() getTime() ``` ### Sintaxis de Marcador de Posicion ```scala val numbers = List(1, 2, 3, 4, 5) numbers.map((x: Int) => x * 2) numbers.map(x => x * 2) numbers.map(_ * 2) // Marcador de posicion para un solo parametro val add = (_: Int) + (_: Int) // Multiples marcadores add(3, 5) // 8 ``` ## Funciones de Orden Superior Funciones que toman funciones como parametros o devuelven funciones: ```scala def applyTwice(f: Int => Int, x: Int): Int = { f(f(x)) } def double(x: Int) = x * 2 applyTwice(double, 5) // 20 (5 * 2 * 2) ``` ### Funciones como Valores de Retorno ```scala def multiplier(factor: Int): Int => Int = { (x: Int) => x * factor } val triple = multiplier(3) triple(5) // 15 ``` ## Closures Un closure es una funcion que captura variables de su scope externo: ```scala var factor = 10 val multiply: Int => Int = (x: Int) => x * factor multiply(5) // 50 factor = 20 multiply(5) // 100 (el closure ve el nuevo valor) ``` ## Currying ### Funciones Curried ```scala def curriedSum(a: Int)(b: Int): Int = a + b curriedSum(3)(5) // 8 val addFive = curriedSum(5) _ addFive(3) // 8 ``` ### Por que Currying? ```scala def withTimestamp(log: String => Unit)(message: String): String = { val timestamp = System.currentTimeMillis() log(s"[$timestamp] $message") message } def logToConsole(msg: String) = println(msg) def logToFile(msg: String) = /* escribir a archivo */ () val timestampedLog = withTimestamp(logToConsole) _ timestampedLog("Hello") // [1234567890] Hello ``` ## Sintaxis Especial de Funciones ### Notacion Infija ```scala object Math { def +(a: Int, b: Int): Int = a.+(b) def -(a: Int, b: Int): Int = a.-(b) } ``` ### Operadores como Metodos ```scala val list = List(1, 2, 3, 4, 5) list.fold(0)(_ + _) // 15 list.foldLeft(0)(_ + _) // Igual (0 /: list)(_ + _) // Igual (foldLeft con operador /:) ``` ## Metodo vs Funcion ### Definicion de Metodo ```scala object Calculator { def add(a: Int, b: Int): Int = a + b } ``` ### Convertir Metodo a Funcion ```scala val addFunction: (Int, Int) => Int = Calculator.add _ addFunction(3, 5) // 8 ``` ## Resumen - Usa `def` para definir funciones - Los parametros tienen tipos explicitos; los tipos de retorno pueden ser inferidos - Parametros por defecto y argumentos nombrados aumentan la flexibilidad - Varargs (`_*`) aceptan numero variable de argumentos - La recursion es fundamental en programacion funcional; usa recursion de cola para eficiencia - Las funciones anonimas proporcionan literales de funcion concisos - Las funciones de orden superior toman o devuelven funciones - Los closures capturan variables del entorno - El currying divide funciones de multiples parametros en cadenas de parametros simples - Los metodos se definen en clases/objetos; las funciones son valores

Comments

Comments powered by Giscus

To enable comments, add your Giscus embed code here.

Learn more about Giscus →