나처럼 옛날 개발자는 별 관심 없던 이름중에 하나가 람다 함수였다. Lisp같은 고오오오급 함수형 프로그래밍에서나 쓴다고 주워듣고 있었는데, 오랫만에 코딩하다보니 필수 아이템이 되어 있네. 아주 새로운 개념은 아니고 실용적으로 간편하게 쓸 수 있는 anonymous function 정도로 알면 될거 같다. Java에서 너저분하게 사용했던 anonymous function의 자리에 lambda function을 넣으면 매우 간결해진다.
python
lambda arguments : expression
위와 같이 정의된다. ‘lambda’라고 명시해주면 끝인정도. python의 경우 lambda expression이 한줄로 표현되므로 expression 값이 리턴값이라고 생각하면 된다.
argument는 여러개가 올 수도 있다. 간단한 예들을 보자.
x = lambda a: a ** 2 # argument의 제곱을 리턴
print(x(5))
x = lambda a, b: a + b # 두개의 arguments의 합을 리턴
print(x(3, 4))
list.sort(), filter(), map(), reduce() 등에 사용하면 편리하다.
sort()의 경우 argument로 ‘key’값에 비교를 위한 함수를 넘기게 된다. 이 함수 자리에 lambda를 쓸 수 있다.
a = [(1, 2), (2, 5), (3, 1), (4, 15)]
a.sort(key=lambda x: x[1]) # tuple의 첫번째 아이템을 sort 비교값으로 준다.
lambda를 더 복잡하게 다루는 자료는 잘 없는데, 대충 둘러봤을 때 가장 잘 정리된 사이트는 코딩도장이었다. 코딩도장 사이트 참조.
Kotlin
가장 잘 설명하고 있는 곳은 공식문서이니 당연히 참조.
Python이 그렇듯, Kotlin도 함수가 first class 값이다. 무슨 뜻이냐면, 변수나 자료구조에 할당하여 저장할 수도 있고, 인자로 전달하거나 리턴값으로 돌려주는게 가능하다. 오래전 C++을 떠올리면 함수포인터나 함수참조를 생각하면 되겠다.
함수를 인자로 전달하거나, 리턴하는 경우 그 타입을 써야하는데 function type이 존재하며 다음과 같은 포맷을 이용한다.
(A, B) -> C
A, B는 인자(argument)타입이고 C 는 리턴값이다. 실제 타입을 사용하면 다음과 같다.
(Int, Double) -> Int
인자가 없는경우, 빈괄호를 써서 ‘() -> C’ 와같이 쓰고, 리턴값이 없는경우는 Unit을 리턴해줘서 ‘(A, B) -> Unit’이 된다.
이 함수타입의 자리에 lambda function이 들어갈 수 있다. lambda function을 만들려면, Python에서는 ‘lambda’키워드를 사용했는데, Kotlin에서 lambda는 중괄호 ‘{}’ 로 묶어준다. 그 형태는 함수타입과 유사하다. 예를들면,
{a: Int, b: Int -> a + b }
a, b는 인자이고 ‘->’ 뒤에 표현식이 나온다. python에서와 마찬가지로 리턴값은 명시적으로 표시할 필요가 없다. Kotlin이 정적 타입언어이므로, 타입을 자동으로 감지하지 못하는 경우 타입도 명시한다.
Kotlin lambda에는 편리한 표현 몇가지가 추가된다. 먼저, 인자가 하나인 경우 인자표시 없이 ‘it’키워드를 사용해 표현식만 쓰면된다. 또한, lambda가 함수의 마지막 인자인 경우, 괄호 밖으로 빼서 사용할 수 있다. 결과적으로 아래 예의 3개가 동일하다.
var ints = listOf(-3, -2, -1, 0, 1, 2, 3, 4, 5)
println(ints.filter({it: Int -> it > 0}))
println(ints.filter({it > 0}))
println(ints.filter{it > 0})
짧아진 표현에 불필요하게 길어지는 괄호표현을 제거함으로서 간단해지고 가독성도 올릴 수 있는걸 알 수 있다.
인자로 넘어오지만 쓰지 않는 것들에 대한 표현방식도 있다. 인자 이름대신 ‘-‘(under score)를 쓰는 것.
map.forEach { _, value -> println("$value!") }
사용되지 않는 인자를 한눈에 식별 가능하다.