본문 바로가기

프로그래밍 언어 기초/KOTLIN

[Kotlin] 함수형 프로그래밍 - 익명 함수(Anonymous function), 람다식(lambda), 클로저(Closure)

개요

오늘은 코틀린의 함수형 프로그래밍에 대해서 알아보도록 하겠습니다.

코틀린은 객체 중심의 프로그래밍에 더하여 함수를 중심으로 한 프로그램의 설계가 가능합니다.

이러한 코틀린만의 프로그래밍 자유도는 개발자의 창의력을 최대로 발휘할 수 있도록 해주고

결과적으로 다양한 프로그램이 탄생할 수 있는 든든한 배경이 됩니다.

앞으로 몇 차례에 걸쳐 다양한 코틀린의 함수형 프로그래밍 기술에 대해 알아보도록 하겠습니다.


익명 함수(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

 

Functions | Kotlin

 

kotlinlang.org