funcs
funcs are first-class citizens in Flowa, meaning they can be assigned to variables, passed as arguments, and returned from other funcs.
Defining funcs
Basic func
func greet(name) {
return "Hello, " + name;
}
let result = greet("Alice");
print(result); // "Hello, Alice"Multiple Parameters
func add(a, b) {
return a + b;
}
func multiply(x, y, z) {
return x * y * z;
}
print(add(3, 4)); // 7
print(multiply(2, 3, 4)); // 24No Return Value
func log_message(message) {
print("[LOG] " + message);
}
log_message("Application started");Return Statement
func is_even(n) {
if (n % 2 == 0) {
return true;
}
return false;
}
// Early return
func divide(a, b) {
if (b == 0) {
return null; // Early return for error case
}
return a / b;
}func as Values
Assigning to Variables
func double(x) {
return x * 2;
}
let my_func = double;
print(my_func(5)); // 10Passing as Arguments
func apply(fn, value) {
return fn(value);
}
func square(x) {
return x * x;
}
let result = apply(square, 5);
print(result); // 25Closures
funcs can capture variables from their surrounding scope:
func create_multiplier(factor) {
func multiply(x) {
return x * factor; // Captures 'factor'
}
return multiply;
}
let double = create_multiplier(2);
let triple = create_multiplier(3);
print(double(5)); // 10
print(triple(5)); // 15Counter Example
func create_counter() {
let count = 0;
func increment() {
count = count + 1;
return count;
}
return increment;
}
let counter = create_counter();
print(counter()); // 1
print(counter()); // 2
print(counter()); // 3Recursive funcs
funcs can call themselves:
func factorial(n) {
if (n <= 1) {
return 1;
}
return n * factorial(n - 1);
}
print(factorial(5)); // 120Fibonacci
func fibonacci(n) {
if (n <= 1) {
return n;
}
return fibonacci(n - 1) + fibonacci(n - 2);
}
print(fibonacci(7)); // 13Sum Array Recursively
func sum_array(arr, index) {
if (index >= len(arr)) {
return 0;
}
return arr[index] + sum_array(arr, index + 1);
}
let numbers = [1, 2, 3, 4, 5];
print(sum_array(numbers, 0)); // 15Variable Scope
Global Variables
let global_var = "I'm global";
func access_global() {
print(global_var); // Can access
}
access_global();Local Variables
func test_scope() {
let local_var = "I'm local";
print(local_var);
}
test_scope();
// print(local_var); // ERROR - undefinedShadowing
let x = "global";
func test_shadow() {
let x = "local"; // Shadows global x
print(x); // "local"
}
test_shadow();
print(x); // "global"Higher-Order funcs
Map func
func map(arr, transform) {
let result = [];
let i = 0;
while (i < len(arr)) {
result = push(result, transform(arr[i]));
i = i + 1;
}
return result;
}
func double(x) {
return x * 2;
}
let numbers = [1, 2, 3, 4, 5];
let doubled = map(numbers, double);
print(doubled); // [2, 4, 6, 8, 10]Filter func
func filter(arr, predicate) {
let result = [];
let i = 0;
while (i < len(arr)) {
if (predicate(arr[i])) {
result = push(result, arr[i]);
}
i = i + 1;
}
return result;
}
func is_even(x) {
return x % 2 == 0;
}
let numbers = [1, 2, 3, 4, 5, 6];
let evens = filter(numbers, is_even);
print(evens); // [2, 4, 6]Reduce func
func reduce(arr, reducer, initial) {
let result = initial;
let i = 0;
while (i < len(arr)) {
result = reducer(result, arr[i]);
i = i + 1;
}
return result;
}
func add(a, b) {
return a + b;
}
let numbers = [1, 2, 3, 4, 5];
let sum = reduce(numbers, add, 0);
print(sum); // 15Anonymous funcs
While Flowa doesn't have arrow funcs, you can define funcs inline:
func apply_to_array(arr, fn) {
let result = [];
let i = 0;
while (i < len(arr)) {
result = push(result, fn(arr[i]));
i = i + 1;
}
return result;
}
// Define func inline
let numbers = [1, 2, 3];
let squared = apply_to_array(numbers, func(x) {
return x * x;
});Practical Examples
User Validator
func validate_user(user) {
if (type(user) != "hash") {
return false;
}
if (!("name" in user) || !("email" in user)) {
return false;
}
if (len(user["name"]) < 2) {
return false;
}
if (!contains(user["email"], "@")) {
return false;
}
return true;
}
let user1 = {"name": "Alice", "email": "alice@example.com"};
let user2 = {"name": "B", "email": "invalid"};
print(validate_user(user1)); // true
print(validate_user(user2)); // falseRetry Logic
func retry(fn, max_attempts) {
let attempt = 0;
while (attempt < max_attempts) {
let result = fn();
if (result != null) {
return result;
}
attempt = attempt + 1;
print("Retry attempt " + tostring(attempt));
}
return null;
}func Composition
func compose(f, g) {
func composed(x) {
return f(g(x));
}
return composed;
}
func add_one(x) {
return x + 1;
}
func double(x) {
return x * 2;
}
let add_then_double = compose(double, add_one);
print(add_then_double(5)); // 12 ((5 + 1) * 2)Best Practices
Single Responsibility
// Good - each func does one thing
func validate_email(email) {
return contains(email, "@");
}
func validate_age(age) {
return age >= 18 && age < 120;
}
func validate_user(user) {
return validate_email(user["email"]) &&
validate_age(user["age"]);
}Meaningful Names
// Good
func calculate_total_price(items) {
// ...
}
// Avoid
func calc(x) {
// ...
}Keep funcs Small
// Break complex funcs into smaller ones
func process_order(order) {
validate_order(order);
calculate_total(order);
apply_discount(order);
send_confirmation(order);
}Next Steps
- Standard Library - Explore built-in funcs
- Standard Library - Explore built-in funcs
- Examples - See practical code examples