Многих эта несовместимость отталкивала от использования Scala в долгосрочных проектах. Неумение или нежелание работать с техдолгом могли всего за несколько лет привести к полному протуханию кодовой базы и невозможности обновить стэк. Я видел энтерпрайз, навечно застрявший на 2.11 без какой-либо надежды на миграцию хотя бы на 2.13, не говоря уже про 3.0.
Повышение версии компилятора и стандартной библиотеки в крупных проектах порой требовало титанических усилий. Например, команда Apache Spark — в своё время одного из главных бустеров популярности Scala — потратила на миграцию на 2.13 больше двух лет и завершила её на днях с выходом версии 3.2.
С самого начала становления экосистемы Scala перед авторами библиотек возник вопрос — как версионировать свои артефакты, чтобы обеспечить их корректное использование на разных версиях компилятора, не превратив управление зависимостями в ад. Появилась концепция cross-building'а — сборки и публикации Maven-артефактов одной версии с разными суффиксами в имени, обозначающими бинарную совместимость с конкретной версией Scala, например
org.typelevel:cats-core_2.13:1.0.0. При всех минусах отсутствия обратной совместимости кроссбилдинг был приемлемым решением, а благодаря поддержке в sbt — и весьма удобным.Команда разработки Scala 3 совершила маленькую революцию — ввела схему версионирования major.minor.patch и гарантировала обратную совместимость для всех будущих версий 3.x.y. Суффикс в именах maven-артефактов сократился до
_3. Старожилы Scala-сообщества сначала не верили в избавление от необходимости кроссбилдить библиотеки под разные субверсии Scala 3, а потом не могли сдержать радости. Ликование усилилось с выходом Scala 3.1, когда каждый мэйнтейнер смог лично убедиться, что библиотеки, опубликованные для 3.0, успешно работают с новым компилятором.Праздник длился всего несколько часов, пока Seth Tisue не запостил трэд, в котором разъяснил все последствия этих изменений. Scala 3 гарантирует обратную совместимость, но не гарантирует, а точнее, вовсе не поддерживает forward-совместимость, во всяком случае пока. Попытка использовать артефакт, полученный от старшей минорной версии компилятора, приводит к ошибкам в compile-time на младшей. Пока что нет и поддержки в sbt, чтобы обнаруживать это во время разрешения зависимостей. А это значит, что библиотекам не стоит спешить с переходом на Scala 3.1, если они не хотят оставлять своих пользователей, по каким-то причинам застрявшим на предыдущей версии компилятора, без дальнейшей поддержки. Ведь теперь нельзя скроссбилдить и опубликовать артефакт под разные версии Scala 3.x, как это было раньше.
На самом деле эта проблема уже много лет существует в Java-экосистеме, где авторам библиотек приходится сидеть в лучшем случае на jdk8. Она же всегда существовала, но оставалась малозаметной и в Scala.js. Но мэйнстримовое Scala-сообщество оказалось к ней не готово. Кто-то вообще её не увидел, кто-то начал сглаживать углы, кто-то — откатывать влитые PR'ы, кто-то — откровенно саботировать любые попытки договориться об общих правилах.
В данный момент дискуссия по существу переехала на Github в комментарии к одному из PR'ов. Наиболее адекватно выглядят аргументы Ross Baker — основного мэйнтейнера http4s, выпустившего за последние месяцы ряд CVE-патчей сразу к четырем активным веткам этого проекта. Он описал разные подходы к решению проблемы, из которых мне ближе всего последний — билдить проекты на разных субверсиях Scala 3, но публиковать пока только под 3.0.2.
P.S. Пока я писал этот пост, вышел официальный анонс релиза Scala 3.1, в котором рекомендуют тот самый Scenario C, предложенный Россом, и обещают сделать всё возможное для добавления forward-compatibility в Scala 3.2.0. Вот это поворот! Надеюсь, у команды компилятора всё получится.