람다 표현식 (Lambda Expression)
정의
람다 표현식은 익명 함수(anonymous function)를 간결하게 표현한 것으로, 함수를 값처럼 다룰 수 있도록 해줍니다. 코틀린에서는 중괄호 {}를 사용하여 정의하며, 변수에 할당하거나 함수 인자로 넘기는 등 일급 시민(first-class citizen) 으로 취급됩니다.
val square = { x: Int -> x * x }
println(square(4)) // 16
람다 표현식의 철학
람다는 단순히 “짧게 쓰는 함수"가 아닙니다. 함수형 프로그래밍의 핵심 철학, 즉 동작을 데이터처럼 다룰 수 있는 능력을 나타냅니다.
람다를 사용하면, 코드의 흐름을 제어하거나 설계를 바꾸지 않고도 기능을 전달할 수 있습니다. 이것은 OOP의 상속과 다형성보다 더 유연한 전략을 제공하며, 전략 패턴의 대체물로도 활용될 수 있습니다.
“인터페이스를 따로 만들 필요 없이, 곧바로 행동을 전달할 수 있는 능력.” — 이것이 람다의 본질적인 힘입니다.
코틀린은 람다를 통해 다음과 같은 설계 철학을 구현합니다:
간결성: 최소한의 문법으로 최대한의 표현
표현력: 이름 없는 함수로도 충분히 의미 전달 가능
조합 가능성: 고차 함수와 조합하여 유연한 API 구성 가능
불- 변성 강조: 상태 없는 함수형 스타일 지향
문법 구조
val 이름: (입력타입) -> 출력타입 = { 매개변수 -> 본문 }
예
val greet: (String) -> String = { name -> "Hello, $name" }
val greet = { name: String -> "Hello, $name" }
고차 함수와 함께 쓰기
람다의 가장 강력한 점은 고차 함수(Higher-Order Function) 와 함께 쓸 때 드러납니다.
fun calculate(x: Int, y: Int, op: (Int, Int) -> Int): Int {
return op(x, y)
}
val sum = calculate(3, 4) { a, b -> a + b } // 7
위 코드는 calculate 함수의 동작을 람다로 주입합니다. 이는 전략 패턴을 코드 수준에서 자연스럽게 표현하는 방식입니다
실무에서의 활용
컬렉션 처리: map, filter, reduce
UI 이벤트 처리: setOnClickListener { … }
DSL 구성 요소: apply, with, build.gradle.kts
비동기 콜백: Retrofit, Coroutine Scope 내부 처리 등
주의할 점
람다 캡처 비용: 외부 변수 캡처 시, 메모리 비용 및 예기치 않은 참조 유지에 주의
남용 금지: 람다로 모든 걸 처리하려 하면 오히려 가독성 하락
타입 명시 생략의 위험: IDE가 추론하더라도 명시가 더 명확할 때가 있음
요약
람다 표현식은 단순한 문법 편의성을 넘어, 행위를 코드로 캡슐화하는 도구입니다.
코드를 데이터처럼 다루는 함수형 사고방식은 선언형 프로그래밍, 조합 가능성 높은 API, 의존성 분리, 상태 최소화 등 현대 소프트웨어 설계에서 매우 중요한 가치를 담고 있습니다.
람다는 읽기 쉽고, 전달 가능하고, 테스트하기 좋은 코드를 설계할 수 있는 핵심 도구입니다.
적절한 곳에 사용하는 람다는 코드 품질을 한 단계 끌어올리는 열쇠가 됩니다.