개요
오늘은 코틀린의 함수형 프로그래밍에 대해서 알아보도록 하겠습니다.
코틀린은 객체 중심의 프로그래밍에 더하여 함수를 중심으로 한 프로그램의 설계가 가능합니다.
이러한 코틀린만의 프로그래밍 자유도는 개발자의 창의력을 최대로 발휘할 수 있도록 해주고
결과적으로 다양한 프로그램이 탄생할 수 있는 든든한 배경이 됩니다.
앞으로 몇 차례에 걸쳐 다양한 코틀린의 함수형 프로그래밍 기술에 대해 알아보도록 하겠습니다.
익명 함수(Anonymous function) vs 람다식(lambda)
함수는 함수의 이름, 함수의 파라미터, 그리고 반환 타입 총 세 가지의 정보로 구성되어 있습니다.
함수의 이러한 구조는 서로 다른 함수를 확실히 구분하는 이점이 되기도 하지만,
때로는 공통된 부분을 추려내거나 간략한 표현식으로 나타낼 때 의도치 않은 제약을 만들기도 합니다.
이러한 개발자의 고민을 해결하고자 프로그래밍 언어 개발진들은
코드를 간결하게 표현하고 함수형 프로그래밍 패러다임을 지원하기 위해
익명 함수와 람다식이라는 기술을 지원하게 되었습니다.
람다식과 익명함수는 함수를 더 간결히 작성할 수 있다는 점에서 서로 공통점을 가지나,
코틀린에서는 상호 간에 명백하게 구분되는 개념입니다.
람다식과 익명 함수의 가장 큰 차이는 다음과 같습니다.
구분 | 람다식(lambda) | 익명 함수(Anonymous function) |
문법 | 중괄호{}를 통해 감싸는 형태 | fun 키워드를 통해 정의 |
반환(return) | 암시적으로 가장 가까운 람다를 둘러싼 함수로부터 값을 반환하거나, return 키워드를 사용하여 명시적으로 반환 |
가장 가까운 익명 함수를 둘러싼 블록으로부터 값을 반환하며, return 키워드를 사용하여 명시적으로 반환 |
val lambda: (Int) -> Int = { x -> x * x }
val anonymousFunction = fun(x: Int): Int { return x * x }
val result1 = lambda(5) // 결과: 25
val result2 = anonymousFunction(5) // 결과: 25
위 코드에서 익명 함수는 fun 키워드를 사용해 함수를 구성하는 반면, 람다식은 더 축약된 형태로 함수를 구성합니다.
람다식과 익명 함수는 비슷한 용도로 사용될 수 있지만,
엄밀히 구분하면 서로 다른 기술이기 때문에 두 기술의 차이점을 알아두면 좋습니다.
람다식의 구조 분해, Destructuring in lambdas
람다식은 이미 코틀린에서 널리 사용하는 기술 중 하나입니다.
가장 대표적인 사례로 코틀린의 forEach 구문을 예로 들 수 있습니다.
fun main() {
val numberList = listOf(1,2,3,4)
numberList.forEach { it ->
println(it);
}
}
위 코드에서 forEach 함수는 람다식의 구조 분해(Destructuring)를 통해
더 깔끔하고 직관적인 코드를 작성할 수 있게 합니다.
클로저(Closures)
클로저란 외부 범위에 있는 변수를 캡처하여 해당 변수가 속한 블록이나 람다 내에서 사용할 수 있는 함수입니다.
클로저를 사용하면 함수 내부에서 외부 범위에 있는 변수를 사용할 수 있으며,
이 변수들의 상태는 함수가 정의된 범위에 영향을 받습니다.
이것은 함수가 정의된 블록의 스코프를 벗어나더라도 해당 변수들이 유지되는 것을 의미합니다.
fun main() {
val message = "Hello, "
// 클로저를 이용하여 외부 범위의 변수를 캡처
val greetingFunction: (String) -> Unit = { name ->
println("$message$name")
}
// 클로저를 호출
greetingFunction("John")
}
위 코드에서 greetingFunction은 외부에 있는 message 변수를 캡처하고 있습니다.
이 함수를 호출하면 "Hello, John"이라는 메시지가 출력됩니다.
greetingFunction은 외부 범위에 있는 변수 message를 사용하는 클로저입니다.
클로저 내부에서 message 변수를 사용하고 있지만,
이 변수는 클로저가 정의된 main 함수의 범위에 있으므로 정상적으로 작동합니다.
클로저를 사용하면 외부 변수의 값이 클로저 내부에서 변경될 수 있으며,
클로저를 정의한 범위에서 변경된 값을 유지합니다.
따라서 클로저는 함수형 프로그래밍에서 상태를 보존하고 전달하는 강력한 도구로 활용할 수 있습니다.
참고 자료
https://kotlinlang.org/docs/functions.html