컨텍스트 바운드
컨텍스트 바운드 (Context Bounds)
많은 상황에서 컨텍스트 파라미터의 이름은 굳이 직접 언급하지 않아도 돼요. 그 이름이 다른 컨텍스트 파라미터를 위한 합성 인자(synthesized argument)에 컴파일러가 사용할 뿐, 우리 코드에서는 쓰일 일이 없거든요. 그럴 때는 파라미터 이름을 아예 정의하지 않고 타입만 적어주면 됩니다.
배경
컬렉션에서 최댓값을 반환하는 메서드 maxElement를 생각해 볼게요.
// Scala 2
def maxElement[A](as: List[A])(implicit ord: Ord[A]): A =
as.reduceLeft(max(_, _)(ord))
// Scala 3
def maxElement[A](as: List[A])(using ord: Ord[A]): A =
as.reduceLeft(max(_, _)(using ord))
maxElement 메서드는 Ord[A] 타입의 컨텍스트 파라미터를 받아서, 그저 max 메서드에 인자로 넘겨주기 위해서만 사용해요.
이해를 돕기 위해 max와 Ord의 정의도 함께 볼게요. (실무에서는 List에 이미 있는 max 메서드를 쓰면 되고, 이 예시는 설명을 위해 만들어 낸 거라는 점만 기억해 두세요.)
// Scala 2
/** Defines how to compare values of type `A` */
trait Ord[A] {
def greaterThan(a1: A, a2: A): Boolean
}
/** Returns the maximum of two values */
def max[A](a1: A, a2: A)(implicit ord: Ord[A]): A =
if (ord.greaterThan(a1, a2)) a1 else a2
// Scala 3
/** Defines how to compare values of type `A` */
trait Ord[A]:
def greaterThan(a1: A, a2: A): Boolean
/** Returns the maximum of two values */
def max[A](a1: A, a2: A)(using ord: Ord[A]): A =
if ord.greaterThan(a1, a2) then a1 else a2
max 메서드도 maxElement처럼 Ord[A] 타입의 컨텍스트 파라미터를 받는 걸 확인할 수 있어요.
컨텍스트 인자 생략하기
max 메서드에서 ord가 컨텍스트 파라미터이므로, maxElement의 구현 안에서 max를 호출할 때 컴파일러가 그 값을 대신 채워 줄 수 있어요.
// Scala 2
def maxElement[A](as: List[A])(implicit ord: Ord[A]): A =
as.reduceLeft(max(_, _))
// Scala 3
def maxElement[A](as: List[A])(using Ord[A]): A =
as.reduceLeft(max(_, _))
max에 명시적으로 넘겨줄 필요가 없으니, maxElement 정의에서는 그 이름을 빼버려도 돼요. 이렇게 이름 없는 컨텍스트 파라미터를 익명 컨텍스트 파라미터(anonymous context parameter) 라고 불러요.
컨텍스트 바운드
이런 배경을 바탕으로, 컨텍스트 바운드(context bound) 는 “타입 파라미터에 컨텍스트 파라미터를 적용한 패턴”을 짧게 표현하는 축약 문법이에요.
컨텍스트 바운드를 쓰면 maxElement 메서드를 이렇게 적을 수 있어요.
// Scala 2 and 3
def maxElement[A: Ord](as: List[A]): A =
as.reduceLeft(max(_, _))
메서드나 클래스의 타입 파라미터 A에 붙은 : Ord 같은 바운드는 Ord[A] 타입의 컨텍스트 파라미터를 의미해요. 내부적으로 컴파일러는 이 문법을 위 배경 섹션에서 본 형태로 변환해 줍니다. 컨텍스트 바운드에 대해 더 알고 싶다면 Scala FAQ의 “컨텍스트 바운드란 무엇인가?” 섹션을 참고하세요.
더 알아보기 (Learn more)
- 원문: Scala 3 Book — Context Bounds
- 컨텍스트 파라미터: Context Parameters
- given import: Given Imports