Folding Results

I have been a full-stack developer for twelve years and am currently part of the Cloud FinOps team at Atlassian. I previously ran an App development agency, managing various teams across design and development, leading web, backend and native mobile app developers in Australia and Europe. My strengths are system architecture design and communicating complicated tech to everyday people. Having helped scale tech at numerous startups, I am passionate about making a positive difference. When not working, you can find me writing tech articles and teaching Javascript and React at SheCodes, an initiative helping to get more women into tech. I regularly give talks on various topics, focusing on the impact the technology we build can have. I am devastated by the state of the world, love a good political rant and can often be swearing at no one in particular. I enjoy building things in JavaScript, Deno and Node.
Kotlin is a fantastic language. Every day, I find a new function or method that makes programming in it a breeze. One of my go-to functions I keep reaching for recently is fold. You can think of fold like a reduce; however, reduce starts with the first value in the list, whereas fold starts with the given initial value and the first item in the list.
An example always helps. We have a list of sites for a business and want to calculate the total staff numbers plus the staff at head office. We can pass the head office staff numbers in as the initial value.
val sites = listOf(
Site("Site A", 150),
Site("Site B", 120),
Site("Site C", 80),
Site("Site D", 200)
)
val headOfficeStaff = 25
val totalStaff = sites.fold(headOfficeStaff) {
total, site -> total + site.staffCount
}
println(totalStaff) // 575
So, we have a good idea of how to use fold now; however, it has some other interesting use cases. When dealing with the Result value in Kotlin, fold can provide some nice syntax sugar when unwrapping the values. Let's use another example.
We want to fetch the carbon footprint for a given account and year. Internally, the function calls a database to get all footprints for an account and returns a Result. We can use fold to process this Result.
fun calculateFootprint(account: String, year: Int): Double? {
return getYearlyFootprintsForAccount(account).fold(
onFailure = { error ->
println("Error fetching data: ${error.message}")
null
},
onSuccess = { yearlyFootprints ->
yearlyFootprints.find { it.year == year }?.carbon
}
)
}
Honestly, I love fold. Not only can you use it for formatting and aggregating data, but it provides a very clean way of processing Result values.



