Functions are first-class citizens in Prady. They can be stored in variables, passed as arguments, returned from other functions, and chained in functional pipelines.
Declaring Functions
Functions are declared using the fn keyword. Parameters require type annotations, and the return type is specified with ->:
fn add(a: Int, b: Int) -> Int {
return a + b;
}
fn greet(name: String) -> Void {
print("Hello, " + name + "!");
}
If a function returns nothing, the return type can be written as Void or omitted entirely.
Anonymous Functions (Lambdas)
Anonymous functions can be defined inline using the fn syntax. Lambdas automatically capture variables from their enclosing lexical scope:
let multiplier = 3;
let triple = fn(x: Int) -> Int {
return x * multiplier;
};
print(triple(10)); // 30
Higher-Order Collection Methods
Prady’s standard collections (List, Array, Set) feature built-in higher-order methods that take lambdas:
filter
Returns a new collection containing only elements for which the predicate lambda returns true:
let numbers = [1, 2, 3, 4, 5, 6, 7, 8];
let evens = numbers.filter(fn(x: Int, i: Int) -> Bool {
return x % 2 == 0;
});
print("Evens: " + evens.join(", ")); // "2, 4, 6, 8"
map
Transforms each element in the collection into a new representation:
let squared = evens.map(fn(x: Int, i: Int) -> Int {
return x * x;
});
print("Squared: " + squared.join(", ")); // "4, 16, 36, 64"
reduce
Accumulates all elements into a single aggregated result:
let sum = numbers.reduce(fn(acc: Int, curr: Int, i: Int) -> Int {
return acc + curr;
}, 0);
print("Total sum: " + sum); // 36
find and some
let hasLarge = numbers.some(fn(x: Int, i: Int) -> Bool {
return x > 5;
}); // true
Next Step: Architecture Contracts
Continue to the hallmark feature of Prady: Architecture-as-Code Contracts to see how the compiler guarantees modular software boundaries.