일급 함수
일급 함수 (First-Class Functions)
Scala는 함수형 프로그래밍 언어에서 기대할 수 있는 기능들을 대부분 갖추고 있어요.
- 람다 (익명 함수)
- 고차 함수 (Higher-Order Functions, HOFs)
- 표준 라이브러리의 불변 컬렉션
람다(익명 함수라고도 해요)는 코드를 간결하면서도 읽기 쉽게 유지하는 데 큰 비중을 차지해요. List 클래스의 map 메서드는 고차 함수의 전형적인 예시인데, 고차 함수란 함수를 파라미터로 받는 함수예요.
아래 두 예시는 동등한 코드로, 리스트의 각 숫자를 2로 곱하는 람다를 map 메서드에 넘기는 방법을 보여줘요.
Scala 2 and 3
val a = List(1, 2, 3).map(i => i * 2) // List(2,4,6)
val b = List(1, 2, 3).map(_ * 2) // List(2,4,6)
이 예시들은 또한 람다 대신 double 메서드를 쓰는 아래 코드와도 동등해요.
Scala 2 and 3
def double(i: Int): Int = i * 2
val a = List(1, 2, 3).map(i => double(i)) // List(2,4,6)
val b = List(1, 2, 3).map(double) // List(2,4,6)
map메서드를 아직 본 적이 없다면,map은 주어진 함수를 리스트의 모든 요소에 적용해서 결과 값들을 담은 새 리스트를 만들어요.
List 같은 컬렉션 클래스의 고차 함수에 람다를 넘기는 것은 Scala 경험의 일부예요. 여러분이 매일 하게 될 일이죠.
불변 컬렉션
List, Vector, 그리고 불변 Map, Set 클래스 같은 불변 컬렉션을 다룰 때 중요한 점이 있어요. 이 함수들은 호출 대상 컬렉션을 변경(mutate)하지 않고, 대신 갱신된 데이터를 담은 새 컬렉션을 반환한다는 거예요. 그 결과 문제를 해결할 때 이들을 "유창한(fluent)" 스타일로 이어 붙이는(chain) 것도 흔해요.
예를 들어 아래 예시는 컬렉션을 두 번 걸러내고(filter), 남은 컬렉션의 각 요소를 곱하는 방법을 보여줘요.
Scala 2 and 3
// a sample list
val nums = (1 to 10).toList // List(1,2,3,4,5,6,7,8,9,10)
// methods can be chained together as needed
val x = nums.filter(_ > 3)
.filter(_ < 7)
.map(_ * 10)
// result: x == List(40, 50, 60)
고차 함수가 표준 라이브러리 곳곳에서 쓰일 뿐 아니라, 여러분이 직접 만들 수도 있어요.
출처: Scala 3 Book
본문
함수형 프로그래밍의 핵심인 "함수는 값이다"라는 생각을 직접 보여주는 장이에요. 람다를 비롯해 함수를 인자로 받는 고차 함수를 쓰는 방법, 그리고 불변 컬렉션에서 메서드를 이어 붙이는 방식을 확인했어요. 이 개념이 익숙해지면 Scala 코드가 훨씬 간결하고 읽기 쉬워져요.