Gosu Blocks and Collections
GuidewireTraining.com faculty · Updated
Definition: A block in Gosu is an anonymous function (Gosu's equivalent of a Java lambda) written with a backslash, such as \ x -> x * 2. Blocks are passed to collection methods like where, map and firstWhere to filter, transform and search lists without writing explicit loops.
Block syntax
A block starts with a backslash, lists its parameters, then an arrow and the body.
var double = \ x : int -> x * 2
print(double(21)) // 42
// Multiple statements use braces and an explicit return
var describe = \ name : String -> {
var trimmed = name.trim()
return "Hello, ${trimmed}"
}
When a block is passed to a method, Gosu usually infers the parameter type, so you can leave it out:
var names = {"Asha", "Ravi", "Meera"}
var longNames = names.where(\ n -> n.length() > 4)
Block types
A variable or parameter that holds a block has a block type, written with the block keyword:
function applyTwice(f : block(x : int) : int, value : int) : int {
return f(f(value))
}
print(applyTwice(\ x -> x + 3, 10)) // 16
Common collection methods
| Method | What it does | Example |
|---|---|---|
where |
Keeps elements that match | vehicles.where(\ v -> v.Year >= 2023) |
map |
Transforms each element | vehicles.map(\ v -> v.Make) |
firstWhere |
First match, or null | drivers.firstWhere(\ d -> d.Excluded) |
hasMatch |
True if any element matches | drivers.hasMatch(\ d -> d.Age < 25) |
allMatch |
True if every element matches | vehicles.allMatch(\ v -> v.Vin != null) |
countWhere |
Counts matches | claims.countWhere(\ c -> c.State == TC_OPEN) |
sum |
Adds a numeric value per element | vehicles.sum(\ v -> v.CostNew) |
each |
Runs a side effect per element | contacts.each(\ c -> print(c.DisplayName)) |
toSet / toList |
Converts the result | vehicles.map(\ v -> v.Make).toSet() |
Methods can be chained, which keeps rules short and readable:
var youngDriverMakes = period.PersonalAutoLine.Vehicles
.where(\ v -> v.Drivers.hasMatch(\ d -> d.PolicyDriver.Age < 25))
.map(\ v -> v.Make)
.toSet()
Capturing variables
A block can use variables from the code around it:
var minYear = 2020
var recent = vehicles.where(\ v -> v.Year >= minYear)
When to use a loop instead
Use a for loop when you need to exit early, update several variables, or when a block chain becomes hard to read. Readability matters more than brevity in code that others will maintain.
Common mistakes
- Calling a collection method on a possibly null array or list (use ?. or check for null first).
- Using where(...).first() when firstWhere(...) states the intent more clearly.
- Running database queries inside a block that executes for every element of a large collection.
- Using map to perform side effects instead of each.
Troubleshooting
- Compile error that the block's parameter type cannot be inferred.
- Declare the parameter type explicitly, for example \ v : PersonalVehicle -> v.Year.
- NullPointerException inside a block.
- An element or a property on it is null. Use the null-safe ?. operator inside the block, or filter nulls first with where(\ x -> x != null).
- A block-heavy rule runs slowly.
- Look for queries or expensive property calls inside the block and move them outside, or filter earlier so the block runs on fewer elements.
Related resources
Examples are simplified for learning. Check exact APIs and behaviour against the documentation for your InsuranceSuite release.