Functions
Functions are first-class values in Nic. They can be passed as arguments, returned from other functions, and stored in variables.
Basic Functions
nic
fn add(a: i32, b: i32) -> i32 {
return a + b;
}
fn greet(name: string) -> unit {
println("Hello, " + name + "!");
return;
}
fn main() -> unit {
let sum: i32 = add(3, 4);
greet("World");
return;
}Parameters and Return Types
Every parameter must have an explicit type. The return type follows ->:
nic
fn multiply(x: i32, y: i32) -> i32 {
return x * y;
}
fn divide(x: f64, y: f64) -> f64 {
return x / y;
}
// No return value uses 'unit'
fn log_message(msg: string) -> unit {
println(msg);
return;
}Function Types
Functions have types and can be stored in variables:
nic
fn double(x: i32) -> i32 {
return x * 2;
}
fn main() -> unit {
// Function type: fn(i32) -> i32
let f: fn(i32) -> i32 = double;
let result: i32 = f(21); // 42
return;
}Higher-Order Functions
Functions that take or return other functions:
nic
fn apply(f: fn(i32) -> i32, x: i32) -> i32 {
return f(x);
}
fn square(n: i32) -> i32 {
return n * n;
}
fn main() -> unit {
let result: i32 = apply(square, 5); // 25
return;
}Lambda Expressions
Anonymous functions (closures) are written with fn:
nic
fn main() -> unit {
// Lambda expression
let double = fn(x: i32) -> i32 { return x * 2; };
let result: i32 = double(21); // 42
// Inline lambda
let squared: i32 = apply(fn(n: i32) -> i32 { return n * n; }, 4);
return;
}
fn apply(f: fn(i32) -> i32, x: i32) -> i32 {
return f(x);
}Closures Capture Variables
Lambdas can capture variables from their enclosing scope:
nic
fn make_adder(n: i32) -> fn(i32) -> i32 {
return fn(x: i32) -> i32 { return x + n; };
}
fn main() -> unit {
let add_10 = make_adder(10);
let result: i32 = add_10(5); // 15
return;
}Visibility
Functions are private by default. Use pub to make them public:
nic
pub fn public_function() -> unit {
return;
}
fn private_function() -> unit {
return;
}External Functions (C FFI)
Declare C functions to call from Nic:
nic
extern fn printf(format: string, ...) -> i32;
extern fn malloc(size: size_t) -> opaque;
extern fn free(ptr: opaque) -> unit;
fn main() -> unit {
printf("Hello from C!\n");
return;
}Exporting to C
Export Nic functions callable from C:
nic
pub extern fn add(a: i32, b: i32) -> i32 {
return a + b;
}
// C can call: int32_t add(int32_t a, int32_t b);Summary
| Feature | Syntax |
|---|---|
| Basic function | fn name(params) -> Type { body } |
| Function type | fn(T1, T2) -> R |
| Lambda | fn(params) -> Type { body } |
| Public | pub fn name(...) -> Type { } |
| External | extern fn name(...) -> Type; |
| Export | pub extern fn name(...) -> Type { } |
Next
Learn about Control Flow to make decisions in your code.