Scala 3 Reference

Scala 3 Reference

스칼라 3는 스칼라 2에 비해 많은 언어 변경과 개선을 구현해요. 이 레퍼런스에서는 설계 결정들을 논의하고 스칼라 2와의 중요한 차이점을 소개해요.

출처: Scala 3 Reference

본문

목표 (Goals)

언어 재설계는 세 가지 주요 목표에 의해 이끌렸어요.

  • 스칼라의 기반을 강화한다. 전체 프로그래밍 언어를 DOT 미적분에 대한 기반 작업과 호환되게 만들고 그 작업에서 배운 교훈을 적용해요.
  • 스칼라를 더 쉽고 안전하게 쓸 수 있게 한다. implicits 같은 강력한 구성을 다듬어 더 부드러운 학습 곡선을 제공해요. 워트(wart)와 퍼즐러를 제거해요.
  • 스칼라 언어 구성의 일관성과 표현력을 더욱 개선한다.

이 목표들에 대응해서, 언어 변경은 일곱 범주로 나뉘어요: (1) 기반을 강화하는 핵심 구성, (2) 언어를 더 쉽고 안전하게 쓰게 하는 단순화와 (3) 제한, (4) 언어를 더 작고 규칙적으로 만드는 제거된 구성, (5) 워트를 제거하고 일관성·유용성을 높이는 변경된 구성, (6) 공백을 메우고 표현력을 높이는 새 구성, (7) 스칼라 2 실험적 매크로를 대체하는 원칙적인 새 메타프로그래밍 접근.

필수 기반 (Essential Foundations)

이 새 구성들은 DOT, 고차 종류, implicit 해석을 위한 SI 계산의 핵심 기능을 직접 모델링해요.

  • 교차 타입(Intersection types), compound types를 대체
  • 합집합 타입(Union types)
  • 타입 람다(Type lambdas), 구조적 타입과 타입 투영을 쓰는 인코딩을 대체
  • given 파라미터에 대한 추상화를 제공하는 컨텍스트 함수(Context functions)

단순화 (Simplifications)

이 구성들은 기존 구성들을 대체해서 언어를 더 안전하고 단순하게 쓰도록 만들고, 코드 스타일의 통일성을 촉진하는 걸 목표로 해요.

  • 트레잇 파라미터는 조기 초기화자를 더 일반적으로 유용한 구성으로 대체해요.
  • given instances는 implicit objects와 defs를 대체하며, 메커니즘보다 의도를 강조해요.
  • using 절은 implicit 파라미터를 대체하며, 그 모호성을 피해요.
  • 확장 메서드는 implicit classes를 더 명확하고 단순한 메커니즘으로 대체해요.
  • 불투명 타입 별칭은 대부분의 값 클래스 사용을 대체하면서 boxing이 없음을 보장해요.
  • 최상위 정의는 패키지 객체를 대체하며, 문법적 보일러플레이트를 없애요.
  • export 절은 집합을 표현하는 간단하고 일반적인 방법을 제공하며, 클래스에서 상속하는 패키지 객체의 이전 파사드 패턴을 대체할 수 있어요.
  • 가변 인자 스플라이스는 이제 함수 인자와 패턴에서 xs: _*xs @ _* 대신 xs* 형태를 사용해요.
  • 보편적 apply 메서드(Universal apply methods)는 new 표현식 대신 간단한 함수 호출 문법을 쓰게 해줘요. new 표현식은 생성자 애플리케이션을 쓸 수 없는 경우의 폴백으로 남아 있어요.

조기 초기화자와 옛 방식 vararg 패턴을 제외하면, 대체된 모든 구성은 스칼라 3.0에서 계속 사용 가능해요. 나중에 폐기하고 단계적으로 없앨 계획이에요.

값 클래스(불투명 타입 별칭으로 대체됨)는 특별한 경우예요. 현재 값 클래스에 대한 폐기 계획은 없어요. JVM이 프로젝트 Valhalla에서 계획한 대로 네이티브로 지원하게 된다면 더 일반적인 형태로 되돌릴 수도 있기 때문이에요.

제한 (Restrictions)

이 구성들은 언어를 더 안전하게 만들기 위해 제한돼요.

  • Implicit Conversions: implicit 변환을 정의하는 방식이 여러 가지가 아니라 단 하나만 있어요. 그리고 잠재적으로 놀랄만한 implicit 변환은 언어 임포트를 요구해요.
  • Given Imports: implicit는 이제 특별한 형태의 import를 요구해서, import를 분명히 보이게 해요.
  • Type Projection: 타입 투영 C#A의 접두사 C로는 클래스만 쓸 수 있어요. 추상 타입에 대한 타입 투영은 타당하지 않으므로 더 이상 지원하지 않아요.
  • Multiversal Equality: ==!=로 의미 없는 비교를 배제하는 "opt-in" 방식을 구현해요.
  • infix: 메서드 적용 문법을 코드 베이스 전반에 걸쳐 통일시켜요.

제한 없는 implicit 변환은 스칼라 3.0에서 계속 사용 가능하지만, 나중에 폐기되고 제거될 거예요. 위 목록의 다른 구성들의 제한 없는 버전은 -source 3.0-migration 아래에서만 사용 가능해요.

제거된 구성 (Dropped Constructs)

이 구성들은 대체하는 새 구성 없이 제거하도록 제안됐어요. 제거 동기는 언어와 그 구현을 단순화하기 위해서예요.

  • DelayedInit,
  • Existential types,
  • Procedure syntax,
  • Class shadowing,
  • XML literals,
  • Symbol literals,
  • Auto application,
  • Weak conformance,
  • Compound types (교차 타입으로 대체됨),
  • Auto tupling (구현됐지만 병합되지 않음).

이 구성들이 제거되는 시기는 다양해요. 현재 상태는 다음과 같아요.

  • 전혀 구현되지 않음: DelayedInit, existential types, weak conformance.
  • -source 3.0-migration 아래에서 지원됨: procedure syntax, class shadowing, symbol literals, auto application, 제한된 형태의 auto tupling.
  • 3.0에서 지원되고 나중에 폐기·단계 제거됨: XML literals, compound types.

변경 (Changes)

이 구성들은 더 규칙적이고 유용하게 만들기 위해 변경되었어요.

  • Structural Types: 이제 플러그 가능한 구현을 허용해서 유용성이 크게 높아졌어요. 일부 사용 패턴은 기존 상태와 비교해 제한돼요.
  • Name-based pattern matching: 기존의 문서화되지 않은 스칼라 2 구현이 약간 단순화된 형태로 규정되었어요.
  • 자동 Eta 확장(Automatic Eta expansion): 이제 기대 타입이 없을 때도 보편적으로 수행돼요. 따라서 후위 _ 연산자는 중복이 됐고, 스칼라 3.0 이후에 폐기·제거될 거예요.
  • Implicit Resolution: implicit 해석 규칙이 더 유용하고 덜 놀랍게 정리되었어요. implicit 범위는 더 이상 패키지 접두사를 포함하지 않도록 제한돼요.

옛 방식 implicit 해석의 대부분 측면은 -source 3.0-migration 아래에서 계속 사용 가능해요. 이 목록의 다른 변경들은 무조건 적용돼요.

새 구성 (New Constructs)

이것들은 언어를 더 강력하거나 쓰기 즐겁게 만드는 추가예요.

  • Enums는 열거형과 대수적 데이터 타입을 위한 간결한 문법을 제공해요.
  • Parameter untupling은 튜플 파라미터 구조 분해에 case를 쓰지 않아도 되게 해줘요.
  • Dependent function types는 의존적 메서드를 의존적 함수 값과 타입으로 일반화해요.
  • Polymorphic function types는 다형 메서드를 다형 함수 값과 타입으로 일반화해요. 현재 상태: 제안과 병합된 프로토타입 구현이 있지만, 구현이 확정되지는 않았어요(특히 타입 추론 지원이 빠져 있어요).
  • Kind polymorphism은 타입과 타입 생성자에 동등하게 작동하는 연산자 정의를 허용해요.
  • @targetName 어노테이션은 다른 언어로 작성된 코드와 상호운용을 더 쉽게 만들고, 이름 충돌을 피하는 데 더 많은 유연성을 줘요.

메타프로그래밍 (Metaprogramming)

다음 구성들은 함께 스칼라의 메타프로그래밍을 새 기반 위에 놓는 것을 목표로 해요. 지금까지 메타프로그래밍은 매크로와, 몇몇 핵심 매크로에 기반한 Shapeless 같은 라이브러리의 조합으로 이루어졌어요. 현재 스칼라 2 매크로 메커니즘은 현재 스칼라 2 컴파일러 위의 얇은 겉장식이라서 취약하고, 많은 경우 스칼라 3로 포팅하는 게 불가능해요.

매크로는 스칼라 2 언어 스펙에 결코 포함되지 않았고 지금까지 -experimental 플래그 아래에서만 사용 가능했다는 점을 주목할 만해요. 이는 매크로의 광범위한 사용을 막지 못했어요.

매크로 사용의 대부분을 포팅할 수 있게 하기 위해, 우리는 아래 나열된 고급 언어 구성들을 실험하고 있어요. 이 설계들은 스칼라 3.0의 나머지 제안 언어 구성들보다 더 잠정적이에요. 최종 릴리스까지 몇 가지 변경이 있을 수 있어요. 메타프로그래밍에 필요한 기능 집합을 안정화하는 것이 우리의 최우선 순위예요.

  • Match Types는 타입에 대한 계산을 허용해요.
  • Inline은 그 자체로 몇몇 간단한 매크로의 직관적인 구현을 제공하고, 동시에 복잡한 매크로 구현의 필수 구성 요소예요.
  • Quotes와 Splices는 통합된 추상화 집합으로 매크로와 스테이징을 표현하는 원칙적인 방법을 제공해요.
  • Type class derivation은 Shapeless의 Gen 매크로와 다른 기반 라이브러리를 언어 내 구현으로 제공해요. 새 구현은 매크로보다 더 견고하고 효율적이며 쓰기 쉬워요.
  • By-name context parameters는 Shapeless의 Lazy 매크로를 더 견고한 언어 내 구현으로 제공해요.

더 보기 (See Also)

제안된 언어 기능의 분류는 이 페이지의 확장 버전으로, 각 언어 구성의 상태(즉 스칼라 3의 일부가 되는 상대적 중요성, 언제 결정할지의 상대적 시급성)와 예상 마이그레이션 비용을 추가해요.

더 알아보기 (Learn more)