바이너리 호환성
바이너리 호환성 (Binary Compatibility)
스칼라 3는 JVM 바이트코드로의 안정적인 인코딩을 가져요. 클래스 파일과 함께 .tasty 확장자 파일을 만들어내는 TASTy 포맷 덕분에, 다른 마이너 버전 간에도 바이너리 호환이 깨지지 않는다는 점을 이 글에서 설명해요.
본문
스칼라 2에서 컴파일러의 다른 마이너 버전들은 다양한 언어 기능을 JVM 바이트코드에 인코딩하는 방식을 자유롭게 바꿀 수 있었어요. 그래서 컴파일러의 마이너 버전이 오를 때마다 바이너리 호환이 깨졌고, 프로젝트에 스칼라 의존성이 하나라도 있으면 모두 그 프로젝트가 쓰는 것과 같은 마이너 스칼라 버전으로 (크로스) 컴파일해야 했죠. 스칼라 3는 이와 달리 JVM 바이트코드로의 안정적인 인코딩을 가져요.
클래스 파일에 더해, 스칼라 3의 컴파일 과정은 .tasty 확장자를 가진 파일도 만들어요. TASTy 포맷은 스칼라 코드의 중간 표현으로, 소스에 대한 전체 정보와 타입 체커(typer)가 제공한 정보를 함께 담고 있어요. 이 정보 중 일부는 바이트코드 생성 중에 유실되기 때문에, 스칼라 3 컴파일러는 컴파일 시 클래스 파일에 더해 TASTy 파일도 읽어서 이미 컴파일된 클래스의 값·메서드 등의 정확한 타입을 알아요. (물론 TASTy 파일만으로 컴파일하는 것도 가능해요.) TASTy 파일은 보통 게시된 아티팩트에서 클래스 파일과 함께 배포되기도 해요.
TASTy 포맷은 확장 가능하지만 하위 호환성을 보존하며, 진화는 언어의 마이너 릴리스 사이에서 일어나요. 이 말은 버전 3.x1.y1의 스칼라 컴파일러가, 버전 3.x2.y2의 다른 컴파일러가 만든 TASTy 파일을 x1 >= x2라면 읽을 수 있다는 뜻이에요. (단, 두 개의 안정 버전 컴파일러를 전제로 해요. SNAPSHOT이나 NIGHTLY 컴파일러 버전은 더 오래된 안정 포맷의 TASTy를 읽을 수 있지만, 같은 마이너 버전의 컴파일러라 해도 그들의 TASTy 버전은 서로 호환되지 않아요. 또한 안정 버전 컴파일러는 불안정 버전이 생성한 TASTy를 읽을 수 없어요.)
TASTy 버전 번호는 <major_version>.<minor_version>-<experimental_version> 형태를 가지며, 언어 릴리스에 맞춰 번호가 병행해서 바뀌어요. 언어 마이너 버전의 증가가 TASTy 마이너 버전의 증가와 대응하죠. (예를 들어 스칼라 3.0.0의 TASTy 버전은 28.0-0이에요.) 실험 버전이 0이면 안정 버전을 뜻하고, 그 외에는 불안정·실험적 버전으로 간주해요. TASTy 버전은 데이터 포맷 자체에만 엄격히 묶이진 않아요. 표준 라이브러리의 API에 어떤 변경이 있어도 TASTy 마이너 버전을 바꿔야 하거든요.