Translate

martes, 4 de junio de 2024

Recursión por cola en Gleam


import gleam/io


pub fn main() {

  io.debug(factorial(5))

  io.debug(factorial(7))

}


pub fn factorial(x: Int) -> Int {

  // The public function calls the private tail recursive function

  factorial_loop(x, 1)

}


fn factorial_loop(x: Int, accumulator: Int) -> Int {

  case x {

    0 -> accumulator

    1 -> accumulator


    // The last thing this function does is call itself

    // In the previous lesson the last thing it did was multiply two ints

    _ -> factorial_loop(x - 1, accumulator * x)

  }

}


Cuando se llama a una función, se crea un nuevo marco de pila en la memoria para almacenar los argumentos y las variables locales de la función. Si se crean muchos de estos fotogramas durante la recursividad, entonces el programa utilizará una gran cantidad de memoria o incluso bloqueará el programa si se alcanza algún límite.

Para evitar este problema, Gleam admite la optimización de llamadas de cola, lo que permite al compilador reutilizar el marco de pila para la función actual si una llamada a función es lo último que hace la función, eliminando el costo de memoria.

Las funciones recursivas no optimizadas a menudo se pueden reescribir en funciones optimizadas de llamada final mediante el uso de un acumulador. Un acumulador es una variable que se pasa además de los datos, similar a una variable mutable en un lenguaje con bucles while.

Los acumuladores deben estar ocultos a los usuarios de su código, son detalles de implementación interna. Para hacer esto, escriba una función pública que llame a una función privada recursiva con el valor inicial del acumulador.