Defining functions
Functions are the building blocks of Quadrate programs. They transform values on the stack.
Basic syntax
fn name(inputs -- outputs) {
// body
}
Every function has:
- A name
- A signature describing stack effects
- A body with the implementation
Your first function
fn square(x:i64 -- result:i64) {
dup *
}
fn main() {
5 square print nl // 25
}
The signature (x:i64 -- result:i64) means:
- Input: Takes one integer
xfrom the stack - Output: Leaves one integer
resulton the stack
Stack effect signature
The -- separates inputs from outputs:
fn sum(a:i64 b:i64 -- result:i64) {
+
}
fn swap_print(a:i64 b:i64 -- ) {
swap print nl print nl
}
fn push_two( -- a:i64 b:i64) {
1 2
}
| Signature | Meaning |
|---|---|
(a:i64 -- b:i64) |
1 input, 1 output |
(a:i64 b:i64 -- c:i64) |
2 inputs, 1 output |
(x:i64 --) |
1 input, no outputs |
(-- x:i64) |
No inputs, 1 output |
() |
No inputs, no outputs |
Parameter names
Parameter names document the values but don't create variables automatically:
use math
fn distance(x1:f64 y1:f64 x2:f64 y2:f64 -- d:f64) {
-> y2 -> x2 -> y1 -> x1 // bind parameters to variables
x2 x1 - dup * // (x2-x1)^2
y2 y1 - dup * // (y2-y1)^2
+ math::sqrt
}
Multiple outputs
Functions can have multiple outputs:
fn divmod(a:i64 b:i64 -- quotient:i64 remainder:i64) {
-> b -> a // bind parameters
a b / // quotient
a b % // remainder
}
fn main() {
17 5 divmod
print nl // 2 (remainder)
print nl // 3 (quotient)
}
Functions without parameters
fn greet() {
"Hello, World!" print nl
}
fn get_answer( -- answer:i64) {
42
}
fn main() {
greet
get_answer print nl // 42
}
The main function
Every program needs a main function:
fn main() {
// Program starts here
}
main takes no inputs and has no outputs.
Function names
Rules for function names:
- Start with a letter or underscore
- Can contain letters, numbers, underscores
- Case-sensitive (
fooandFooare different)
fn calculate_total() { }
fn processItem2() { }
Type annotations
Always specify types for parameters:
| Type | Description |
|---|---|
i64 |
64-bit integer |
f64 |
64-bit float |
str |
String |
ptr |
Pointer |
bool |
Boolean (alias for i64) |
fn format_price(price:f64 currency:str -- formatted:str) {
-> currency -> price
// ... implementation
}
Documentation comments
Use /// for documentation:
/// Calculates the factorial of n
/// @param n The number to calculate factorial of
/// @output The factorial result
fn factorial(n:i64 -- result:i64) {
-> n // bind parameter
n 1 <= if {
1
} else {
n n 1 - factorial *
}
}
What's next?
Now let's learn how to Call Functions and chain them together.