Functions
What is a function?
A function is a reusable block of instructions with a name. Think of it like a recipe: you define the steps once, and then you can use the recipe whenever you need it without writing the steps again.
You have already been using functions: main() is a function, and print() is a function built into Nyx.
Defining a function
fn greet() { print("Hello!") print("Welcome to Nyx.") } fn main() { greet() // call the function greet() // call it again }
Output:
Hello! Welcome to Nyx. Hello! Welcome to Nyx.
The function is defined once but called twice. Each call executes all the instructions inside the function.
Parameters — giving data to a function
Functions can receive inputs, called parameters:
fn greet(name: String) { print("Hello, " + name + "!") } fn main() { greet("Alice") // Hello, Alice! greet("Bob") // Hello, Bob! greet("Charlie") // Hello, Charlie! }
Multiple parameters are separated by commas:
fn add(a: int, b: int) { print(a + b) } fn main() { add(3, 5) // 8 add(10, 20) // 30 }
Return values — getting data back from a function
Functions can send a result back using return:
fn square(n: int) -> int { return n * n } fn main() { let result: int = square(5) print(result) // 25 print(square(8)) // 64 }
The -> int after the parameters declares what type the function returns. The return keyword sends the value back to whoever called the function.
Functions that return different types
fn is_adult(age: int) -> bool { return age >= 18 } fn full_name(first: String, last: String) -> String { return first + " " + last } fn main() { print(is_adult(25)) // true print(is_adult(12)) // false print(full_name("Alice", "Smith")) // Alice Smith }
Recursion — a function calling itself
A function can call itself. This is called recursion:
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 }
How it works:
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
Every recursive function needs a base case — a condition where it stops calling itself. Without it, the function would call itself forever.
Classic example: 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 }
Functions as building blocks
Good programs are built from small, focused functions. Each function does one thing well:
fn celsius_to_fahrenheit(c: float) -> float { return c * 9.0 / 5.0 + 32.0 } fn is_freezing(temp_c: float) -> bool { return temp_c <= 0.0 } fn describe_temperature(c: float) -> String { let f: float = celsius_to_fahrenheit(c) if is_freezing(c) { return "Freezing!" } if c > 35.0 { return "Very hot!" } return "Comfortable" } fn main() { print(describe_temperature(0.0)) // Freezing! print(describe_temperature(22.0)) // Comfortable print(describe_temperature(40.0)) // Very hot! }
Notice how describe_temperature calls celsius_to_fahrenheit and is_freezing. Functions can call other functions — this is how you build complex programs from simple pieces.
Functions without return
If a function doesn't return anything, you can omit the -> part:
fn say_hello(name: String) { print("Hello, " + name) // no return statement needed } fn main() { say_hello("Alice") }
Exercises
- Write a function
max(a: int, b: int) -> intthat returns the larger of two numbers.
- Write a function
is_even(n: int) -> boolthat returnstrueif a number is even.
- Write a function
power(base: int, exp: int) -> intthat calculates base raised to the power of exp using a while loop (not recursion).
- Write a function
count_digits(n: int) -> intthat returns how many digits a positive number has. Hint: keep dividing by 10 until you reach 0.
- Write a function
gcd(a: int, b: int) -> intthat computes the greatest common divisor using Euclid's algorithm: ifbis 0, returna; otherwise, returngcd(b, a % b).
Summary
fn name(params) -> ReturnType { ... }defines a function.- Parameters let you pass data in.
returnsends data back.- Recursion is when a function calls itself (needs a base case).
- Build programs from small, focused functions.
- Functions without a return value omit the
->part.
Next chapter: Arrays →