저는 코틀린을 배우기 전에 C언어를 공부했습니다. 코틀린을 배우니 '람다' 라고 하는 처음 들어보는 친구가 등장하더군요. 그래서 궁금해졌습니다. C언어에는 없는 람다, 코틀린에는 왜 있는거지?
결론부터 말하자면, 코틀린은 ‘함수형 프로그래밍’을 지원하는 언어이기 때문입니다.
함수형 프로그래밍은 순수 함수를 작성하여 프로그램의 부작용을 줄이는 프로그래밍 기법을 말하며 람다식과 고차함수를 사용합니다. 따라서 코틀린에서 람다식을 사용하는 이유는 함수형 프로그래밍 규칙을 따르기 위해서 라고 볼 수 있겠습니다.
참고로, 코틀린은 함수형 프로그래밍과 객체 지향 프로그래밍을 모두 지원하는 ‘다중 패러다임 언어’ 입니다. 여기서 다중 패러다임 언어는 한 가지 구현 규칙에 얽매이지 않고 다양한 문법과 형식을 지원하는 언어를 말하며, 현대 컴퓨터 언어는 다중 패러다임 언어를 지향하며 발전하고 있다고 합니다.
순수 함수가 되기 위해서는 두 가지 조건을 충족해야 합니다.
- 같은 인자에 대하여 항상 같은 값을 반환한다. = ‘부작용이 없는 함수’
- 함수 외부의 어떤 상태도 바꾸지 않는다.
fun sum(a : Int, b: Int) : Int {
return a+b
}
위 예시를 보면, 매개변수 a, b 로 들어온 인자에 대해서 항상 a*b 를 반환하는 것을 알 수 있습니다. 그리고 함수 안에서 함수 외부의 어떤 변수도 바꾸지 않지요. 따라서 위는 순수함수입니다.
fun check() {
val test = User.grade()
if (test != null) process(test)
}
하지만 위의 예시를 보면, User 객체의 grade 함수의 반환값이 무엇인지에 따라서 process 함수가 실행될 수도 있고 안 될 수도 있습니다. 즉, check 함수의 실행 결과를 예측하기 어렵습니다. 이런 함수는 순수함수의 조건을 만족하지 못하는 함수입니다.
함수형 프로그래밍의 특징 중 하나인 람다식에 대해서 살펴보겠습니다.
람다식은 람다 대수에서 유래한 것으로 다음과 같은 형태입니다.
{ x, y -> x + y }
수학에서 말하는 람다 대수는 이름이 없는 함수로 2개 이상의 입력을 1개의 출력으로 단순화 한다는 개념입니다. 그런데 함수형 프로그래밍의 람다식은
- 다른 함수의 인자로 넘기는 함수,
- 함수의 결괏값으로 반환하는 함수,
- 변수에 저장하는 함수를 말합니다.
함수형 프로그래밍에서는 함수를 일급객체로 생각합니다.
람다식 역시 일급객체의 특징을 가지고 있습니다.
일급객체(first class citizen)의 특징을 살펴보겠습니다.
- 일급 객체는 함수의 인자로 전달할 수 있다.
- 일급 객체는 함수의 반환값에 사용할 수 있다.
- 일급 객체는 변수에 담을 수 있다.
만약 함수가 일급 객체이면 ‘일급함수’ 라고 부릅니다. 그리고 일급함수에 이름이 없는 경우, ‘람다함수’ 또는 ‘람다식’ 이라고 부르는 것입니다.
즉, 람다식은 일급 객체의 특징을 가진, 이름 없는 함수인 것이지요.
고차함수는 다른 함수를 인자로 사용하거나, 함수를 결과값으로 반환하는 함수를 말합니다. 일급 객체 혹은 일급 함수를 서로 주고 받을 수 있는 함수가 고차함수가 되는 것이지요.
fun main() {
println(highFunc( { x, y -> x + y}, 10, 20)
}
fun highFunc(sum : (Int, Int) -> Int, a : Int, b : Int) : Int = sum(a, b)
위의 highFunc 함수는 { x, y -> x + y } 람다식을 인자로 받고 있습니다. 이렇게 일급객체를 받을 수 있는 함수를 고차함수라고 합니다.
지금까지 코틀린의 입장(?)에서 본 함수형 프로그래밍에 대해서 살펴보았는데요, 함수형 프로그래밍의 정의와 특징을 정리하면 다음과 같습니다.
- 순수함수를 사용해야 한다.
- 람다식을 사용할 수 있다.
- 고차함수를 사용할 수 있다.
다음 포스트에서는 람다식과 고차함수를 조금 더 구체적으로 살펴보도록 하겠습니다!
위 포스트는 Do it! 코틀린 프로그래밍 서적을 참고해서 쓰여졌습니다. 더욱 자세한 내용은 책을 참고해주세요!
잘 읽혀요!
좋은 글 감사합니다~