부작용 (side-effect)이 없는 함수
⭐ 순수 함수의 조건
- 같은 인자에 대하여 항상 같은 값을 반환한다.
- 함수 외부의 어떤 상태도 바꾸지 않는다.
그렇다면, 순수 함수가 아닌 것은?
fun check(){
val test = User.grade() // 외부 객체 User 사용
if(test != null) process(test)
}
check() 함수 외부에 정의된 User 객체의 상태에 따라, check 함수의 반환 값이 달라질 수 있다. 또한, User 객체의 grade() 함수에 의해 외부 상태가 변경되는 부작용이 발생할 수도 있다. 따라서, check() 함수는 순수 함수가 아니다.
package chap03.section2
const val global = 10
fun main() {
val num1 = 10
val num2 = 3
val result = foo(num1, num2)
println(result)
}
fun foo(a: Int, b: Int): Int {
return a + b + global
}
foo 함수의 입력값과 무관하게 전역 변수에 따라 함수의 반환값이 달라질 수 있다. 따라서 foo 함수는 순수 함수가 아니다.
이를 통해 프로그래밍의 유연성이 증가한다.
람다식의 예 (이름이 없는 함수 형태)
👉 { x, y -> x + y }
람다식은 고차 함수에서 인자로 넘기거나 결과 값으로 반환할 수 있다.
고차 함수 (high-order function)란 다른 함수를 인자로 사용하거나 함수를 결과 값으로 반환하는 함수를 말한다. 물론 두 특징을 모두 가지고 있어도 고차 함수라고 얘기한다. 일급 객체 혹은 일급 함수를 서로 주고 받을 수 있는 함수가 고차 함수가 되는 것이다.
람다식을 함수의 가장 마지막 인자로 사용하면, 함수 호출 시 람다식의 중괄호를 밖으로 뺄 수 있다! 람다식의 내용이 길어지는 경우 이 방법이 편리하게 사용된다!
package chap03.section2
fun highFunc(a: Int, b: Int, sum: (Int, Int) -> Int): Int {
return sum(a, b)
}
fun main() {
//val result = highFunc(10, 20, { x, y -> x + y })
val result = highFunc(10, 20) { x, y ->
x + y
} // 요렇게 중괄호를 밖으로 빼서 람다식을 작성할 수 있다!
println(result)
}
함수형 프로그래밍은 순수 함수를 조합해 외부의 상태 변경이나 부작용이 없는 루틴을 만들어낸다. 그리고 이름 없는 함수 형태의 하나인 람다식을 이용해 함수를 (마치 변수처럼) 매개변수, 인자, 리턴값 등에 활용하는 고차 함수를 구성하여, 생산성을 높인 프로그래밍 방법이다!