Closures & Lambdas
Closures (anonymous functions or lambdas) are first-class blocks of code that can be stored in variables, passed to higher-order functions, and capture bindings from their lexical scope.
Lambda Syntax Styles
Autolang supports both Kotlin-style arrow lambdas { x: Int -> ... } and pipe-delimited lambdas {|x: Int| ... }. For single-argument lambdas where the parameter name is omitted, the implicit identifier it is automatically available.
// 1. Kotlin-style arrow lambda with explicit types
val add = { x: Int, y: Int -> x + y }
println(add(10, 20)) // 30
// 2. Inferred parameter types
val multiply: (Int, Int) -> Int = { a, b -> a * b }
println(multiply(6, 7)) // 42
// 3. Single-parameter lambda with implicit 'it'
val doubleVal: (Int) -> Int = { it * 2 }
println(doubleVal(25)) // 50
// 4. Zero-parameter lambda returning a value
val getDefaultPort = { 8080 }
println(getDefaultPort()) // 8080
// 5. Pipe syntax style
val square = {|n: Int| n * n }
println(square(5)) // 25Trailing Lambda Syntax
When the last parameter of a function is a lambda, the closure can be moved outside the argument parentheses. If the closure is the only argument, the parentheses can be omitted entirely.
fun executeWithRetry(retries: Int, task: (Int) -> Bool): Bool {
var attempt = 1
while (attempt <= retries) {
if (task(attempt)) return true
attempt += 1
}
return false
}
// Trailing lambda placed outside parentheses
val success = executeWithRetry(3) { attemptNumber ->
println("Running attempt " + attemptNumber)
attemptNumber == 2
}
println("Task succeeded: " + success)
// Standard collection method with trailing lambda
val values = [10, 25, 40, 55]
val highValues = values.filter { it > 30 }
println("Filtered: " + highValues.joinToString(", ")) // 40, 55Variable Capturing by Reference
Closures in Autolang capture variables from their outer scope by reference. This allows closures to read current values dynamically and mutate outer variables directly.
var cumulativeRevenue = 0
val addSale = { amount: Int ->
cumulativeRevenue += amount
}
addSale(1500)
addSale(2500)
println("Total revenue: " + cumulativeRevenue) // 4000
// Factory returning stateful counter closure
fun createSequenceGenerator(): () -> Int {
var counter = 0
return {
counter += 1
counter
}
}
val nextId = createSequenceGenerator()
println("Id 1: " + nextId()) // 1
println("Id 2: " + nextId()) // 2Collection Scope Builders
Use buildList and buildMap to construct immutable collections within a dedicated lambda scope.
val permissionList = buildList<String> {
it.add("READ_ORDERS")
it.add("EXECUTE_PAYMENTS")
it.add("VIEW_AUDIT_LOGS")
}
println("Configured permissions: " + permissionList.size()) // 3
val serviceEndpoints = buildMap<String, String> {
it.put("crm", "https://crm.internal")
it.put("billing", "https://billing.internal")
}
println("CRM endpoint: " + serviceEndpoints.get("crm"))