Índice

Funciones

¿Qué es una función?

Una función es un bloque reutilizable de instrucciones con un nombre. Piensa en ella como una receta: defines los pasos una vez, y después puedes usar la receta cuando la necesites sin escribir los pasos de nuevo.

Ya has estado usando funciones: main() es una función, y print() es una función incorporada en Nyx.

Definir una función

fn saludar() {
    print("¡Hola!")
    print("Bienvenido a Nyx.")
}

fn main() {
    saludar()    // llamar la función
    saludar()    // llamarla de nuevo
}

La función se define una vez pero se llama dos veces. Cada llamada ejecuta todas las instrucciones dentro de la función.

Parámetros — darle datos a una función

Las funciones pueden recibir entradas, llamadas parámetros:

fn saludar(nombre: String) {
    print("¡Hola, " + nombre + "!")
}

fn main() {
    saludar("Alicia")     // ¡Hola, Alicia!
    saludar("Roberto")    // ¡Hola, Roberto!
}

Múltiples parámetros se separan con comas:

fn sumar(a: int, b: int) {
    print(a + b)
}

fn main() {
    sumar(3, 5)      // 8
    sumar(10, 20)    // 30
}

Valores de retorno — obtener datos de vuelta

Las funciones pueden enviar un resultado de vuelta usando return:

fn cuadrado(n: int) -> int {
    return n * n
}

fn main() {
    let resultado: int = cuadrado(5)
    print(resultado)       // 25
    print(cuadrado(8))     // 64
}

El -> int después de los parámetros declara qué tipo retorna la función. La palabra return envía el valor de vuelta a quien llamó la función.

Recursión — una función que se llama a sí misma

Una función puede llamarse a sí misma. Esto se llama recursión:

fn factorial(n: int) -> int {
    if n <= 1 {
        return 1
    }
    return n * factorial(n - 1)
}

fn main() {
    print(factorial(5))     // 120 (5 × 4 × 3 × 2 × 1)
    print(factorial(10))    // 3628800
}

Cómo funciona:

factorial(5)
= 5 * factorial(4)
= 5 * 4 * factorial(3)
= 5 * 4 * 3 * factorial(2)
= 5 * 4 * 3 * 2 * factorial(1)
= 5 * 4 * 3 * 2 * 1
= 120

Toda función recursiva necesita un caso base — una condición donde deja de llamarse a sí misma. Sin él, la función se llamaría a sí misma para siempre.

Ejemplo clásico: Fibonacci

fn fibonacci(n: int) -> int {
    if n <= 0 { return 0 }
    if n == 1 { return 1 }
    return fibonacci(n - 1) + fibonacci(n - 2)
}

fn main() {
    var i: int = 0
    while i <= 10 {
        print(fibonacci(i))
        i += 1
    }
    // 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55
}

Funciones como bloques de construcción

Los buenos programas se construyen con funciones pequeñas y enfocadas. Cada función hace una cosa bien:

fn celsius_a_fahrenheit(c: float) -> float {
    return c * 9.0 / 5.0 + 32.0
}

fn esta_helando(temp_c: float) -> bool {
    return temp_c <= 0.0
}

fn describir_temperatura(c: float) -> String {
    if esta_helando(c) {
        return "¡Helando!"
    }
    if c > 35.0 {
        return "¡Muy caliente!"
    }
    return "Confortable"
}

fn main() {
    print(describir_temperatura(0.0))     // ¡Helando!
    print(describir_temperatura(22.0))    // Confortable
    print(describir_temperatura(40.0))    // ¡Muy caliente!
}

Nota cómo describir_temperatura llama a celsius_a_fahrenheit y esta_helando. Las funciones pueden llamar a otras funciones — así es como construyes programas complejos a partir de piezas simples.

Ejercicios

  1. Escribe una función maximo(a: int, b: int) -> int que retorne el mayor de dos números.
  2. Escribe una función es_par(n: int) -> bool que retorne true si un número es par.
  3. Escribe una función potencia(base: int, exp: int) -> int que calcule base elevada a la potencia de exp usando un bucle while.
  4. Escribe una función contar_digitos(n: int) -> int que retorne cuántos dígitos tiene un número positivo.
  5. Escribe una función mcd(a: int, b: int) -> int que calcule el máximo común divisor usando el algoritmo de Euclides.

Resumen

Siguiente capítulo: Arrays →

← Anterior: Control de flujo Siguiente: Arrays →