일급 함수

일급 함수 (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 코드가 훨씬 간결하고 읽기 쉬워져요.

더 알아보기 (Learn more)