Introdução à Programação Funcional em Kotlin
Kotlin é uma linguagem moderna e multiparadigma que combina organicamente programação orientada a objetos e funcional. O estilo funcional permite escrever código mais previsível, conciso e testável. Neste artigo, vamos abordar os conceitos-chave da programação funcional (PF) em Kotlin: funções puras, imutabilidade de dados, funções de alta ordem e trabalho com coleções através de map, filter e fold. O material é voltado para desenvolvedores que já conhecem os fundamentos da sintaxe do Kotlin.
Funções Puras e Imutabilidade
O que é uma função pura?
Uma função pura é uma função que:
- Sempre retorna o mesmo resultado para os mesmos argumentos (determinismo).
- Não tem efeitos colaterais (não altera o estado externo, não lê variáveis globais, não realiza entrada/saída).
Exemplo de função pura:
fun sum(a: Int, b: Int): Int = a + bExemplo de função impura (depende do estado externo):
var counter = 0fun impureSum(a: Int, b: Int): Int { counter++ // efeito colateral return a + b}Imutabilidade (immutability)
Na PF, é comum evitar alterar dados após sua criação. Em Kotlin, para isso, utilizam-se:
valem vez devarpara declarar referências imutáveis.- Coleções imutáveis:
listOf,mapOf,setOf. - Cópia de objetos com alterações através de
copy()para data classes.
data class User(val name: String, val age: Int)
fun main() { val user = User("Alice", 25) val updatedUser = user.copy(age = 26) // criamos uma nova cópia println(user) // User(name=Alice, age=25) println(updatedUser) // User(name=Alice, age=26)}Vantagens da imutabilidade: simplificação da depuração, segurança em threads, previsibilidade do código.
Funções de Alta Ordem e Expressões Lambda
Funções como valores
Em Kotlin, funções podem ser passadas como argumentos, retornadas de outras funções e armazenadas em variáveis. Esta é a base do estilo funcional.
// Função que recebe outra funçãofun operateOnNumbers(a: Int, b: Int, operation: (Int, Int) -> Int): Int { return operation(a, b)}
fun main() { val sum = operateOnNumbers(5, 3) { x, y -> x + y } val product = operateOnNumbers(5, 3) { x, y -> x * y } println("Soma: $sum, Produto: $product")}Expressões Lambda
Uma lambda é uma função anônima escrita de forma compacta. Sintaxe: { argumentos -> corpo }.
val square: (Int) -> Int = { x -> x * x }val result = square(4) // 16
// Se houver apenas um argumento, podemos usar o nome implícito itval double: (Int) -> Int = { it * 2 }Funções de alta ordem embutidas
Kotlin fornece diversas funções úteis para trabalhar com coleções:
map— transforma cada elemento.filter— mantém os elementos que satisfazem uma condição.fold— reduz a coleção a um único valor com um acumulador inicial.
fun main() { val numbers = listOf(1, 2, 3, 4, 5)
// map: elevar ao quadrado val squares = numbers.map { it * it } println(squares) // [1, 4, 9, 16, 25]
// filter: manter apenas os pares val evens = numbers.filter { it % 2 == 0 } println(evens) // [2, 4]
// fold: soma de todos os elementos val sum = numbers.fold(0) { acc, element -> acc + element } println(sum) // 15
// Encadeamento de chamadas: quadrados pares val evenSquares = numbers .filter { it %
```