이름에 의한 컨텍스트 파라미터

이름에 의한 컨텍스트 파라미터 (By-Name Context Parameters)

컨텍스트 파라미터는 발산하는(diverging) 추론된 확장을 피하기 위해 이름에 의한 파라미터(by-name parameter)로 선언할 수 있어요. 예를 들면 이런 코드죠.

trait Codec[T]:
  def write(x: T): Unit

given intCodec: Codec[Int] = ???

given optionCodec: [T] => (ev: => Codec[T]) => Codec[Option[T]]:
  def write(xo: Option[T]) = xo match
    case Some(x) => ev.write(x)
    case None =>

val s = summon[Codec[Option[Int]]]

s.write(Some(33))
s.write(None)

일반적인 이름에 의한 파라미터의 경우와 마찬가지로, 컨텍스트 파라미터 ev의 인자는 필요할 때 평가돼요. 위 예시에서 옵션 값 xNone이면 ev는 전혀 평가되지 않아요.

컨텍스트 파라미터를 위해 합성된 인자는, 그렇지 않으면 발산하는 확장을 막는 데 필요하다면 지역 val로 뒷받침돼요.

타입 => T의 이름에 의한 컨텍스트 파라미터에 대한 인자를 합성하는 정확한 단계는 다음과 같아요.

  1. 타입 T의 새 given을 만듭니다.
given lv: T = ???

여기서 lv는 임의의 새로운(fresh) 이름이에요. 이 given은 인자 추론의 후보로 즉시 사용할 수 없어요. (즉시 사용 가능하게 만들면 합성된 계산에서 루프가 생길 수 있거든요.) 하지만 이름에 의한 컨텍스트 파라미터의 인자를 다시 찾는 모든 중첩된 컨텍스트에서는 사용할 수 있게 돼요.

  1. 그 검색이 표현식 E로 성공하고, Elv에 대한 참조를 포함한다면, E를 다음처럼 바꿉니다.
{ given lv: T = E; lv }
  1. 그렇지 않으면 E를 그대로 돌려줍니다.

위 예시에서 s의 정의는 다음과 같이 확장돼요.

val s = summon[Test.Codec[Option[Int]]](
  using optionCodec[Int](using intCodec)
)

합성된 인자가 재귀적이지 않기 때문에 지역 given 인스턴스는 생성되지 않았어요.

출처: Scala 3 Reference

더 알아보기 (Learn more)

자세한 내용은 Issue #1998과 관련 Scala SIP을 참고하세요.