Saltar al contenido

Retornos Múltiples y Recursión

En esta página

En Zolo, el retorno múltiple se modela como un array homogéneo: el tipo de retorno es [T] y quien llama desestructura con let (a, b) = f(). Esto evita crear un struct solo para agrupar dos o tres valores relacionados:

divmod, min_max y version — desestructuración por posición.

05-multi-return.zolo
Playground
// Feature: Multiple return via array

// Syntax: `fn f() -> [T] { return [a, b, c] }` + `let (x, y, z) = f()`

// When to use: return two or three related values without

// creating a struct — the classic div/mod, min/max, ok+value.

//

// In Zolo, "tuples" at the value site are arrays: the return type

// is `[T]` (homogeneous array) and destructuring extracts by position.


fn divmod(a: int, b: int) -> [int] {
  return [a / b, a % b]
}

let (q, r) = divmod(17, 5)
print("{q} remainder {r}")  // 3 remainder 2


// Min/max in a single pass.

fn min_max(arr: [int]) -> [int] {
  var lo = arr[0]
  var hi = arr[0]
  for x in arr {
    if x < lo { lo = x }
    if x > hi { hi = x }
  }
  return [lo, hi]
}

let (lo, hi) = min_max([3, 1, 4, 1, 5, 9, 2, 6])
print("lo={lo} hi={hi}")  // lo=1 hi=9


// Triples work the same — destructure by position.

fn version() -> [int] {
  return [1, 2, 3]
}

let (maj, min, patch) = version()
print("v{maj}.{min}.{patch}")  // v1.2.3


// For heterogeneous types, use a typed array as `[any]`-like

// (without annotation the inferrer accepts mixed literals).

fn lookup(ok: bool) -> [str] {
  if ok {
    return ["ok", "all good"]
  }
  return ["err", "went wrong"]
}

let (status, msg) = lookup(true)
print("{status}: {msg}")  // ok: all good

La recursión funciona de forma natural: una función puede llamarse a sí misma, y el compilador resuelve las referencias en cualquier orden. Para casos donde la profundidad de llamada sería alta, la forma acumulador (tail-style) es preferible. La recursión mutua — dos funciones que se llaman entre sí — también está soportada:

Factorial, Fibonacci naive y con acumulador, is_even/is_odd mutuamente recursivos.

09-recursion.zolo
Playground
// Feature: Recursion (direct and mutual)

// Syntax: `fn f() { ...f()... }` — fn can call itself.

// When to use: naturally recursive structures (trees,

// lists), divide-and-conquer, mathematical definitions.


// Classic factorial.

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

print(factorial(5))  // 120

print(factorial(10))  // 3628800


// Naive Fibonacci (just for show, not efficient).

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

for i in 0..10 {
  print("fib({i}) = {fib(i)}")
}

// Fibonacci with accumulator ("tail-style" recursion).

fn fib_iter(n: int, a: int, b: int) -> int {
  if n == 0 { return a }
  return fib_iter(n - 1, b, a + b)
}

fn fib_fast(n: int) -> int {
  return fib_iter(n, 0, 1)
}

print(fib_fast(20))  // 6765


// MUTUAL recursion — two functions calling each other.

fn is_even(n: int) -> bool {
  if n == 0 { return true }
  return is_odd(n - 1)
}

fn is_odd(n: int) -> bool {
  if n == 0 { return false }
  return is_even(n - 1)
}

print(is_even(10))  // true

print(is_odd(7))  // true


// Sum of array via recursion.

fn sum_arr(arr: [int], i: int) -> int {
  if i >= arr.len() { return 0 }
  return arr[i] + sum_arr(arr, i + 1)
}

print(sum_arr([1, 2, 3, 4, 5], 0))  // 15

Desafío

Escribe powers(base: int, max: int) -> [int] que devuelva [base^0, base^1, ..., base^max] usando recursión, y desestructura los tres primeros resultados al llamarla.

Consulta también

Buscar en Zolo

9 resultados

enespt-br