I think the biggest missed opportunity is compile times: I think that if we can provide significant compilation time wins, people will migrate to Scala 3, and eat the migration pain, without any new features at all! In case people have forgotten, in the recent Scala Developer Survey (marginally) more people wanted faster compile times than every other language feature/improvement combined.
Different work from trying to judge new features on their “elegance” or “simplicity”, but if you can show people Scala code compiling 2x as fast (which is not unreasonable: that was about the improvement from 2.10.0 to 2.12.8) people will jump through as many hoops as you’d like them to. Reactive-Akka developers, Scalaz/Cats developers, Better-Java developers, Scala-JS-React developers may disagree on the elegance of implicit function types or the new typeclass syntax, but everyone would agree that improved compile times would be a huge carrot that is hard to turn down, especially in professional environments with large codebases.
If we think the Dotty Scala codebase is so much easier to work with (I presume we do, because otherwise why would it be worth spending a decade rewriting NSC), and it has not been micro-optimized-to-the-moon like Scalac has, then it should be significantly easier to get significant wins. The fact that the language is simpler for humans to reason about should surely also make it simpler for machines to analyze.
I don’t think metaprogramming migration is going to be that hard. The main difficulty is just getting something that we can migrate to, which has not existed for the past 5 years. I write a lot of macros, in a lot of OSS libraries, and it shouldn’t take me more than a week or two to re-write all my macros using whatever meta-programming library you’d like, as long as it supports the same use cases.
The last “supports the same use cases” line is key. Past work on Metaprogramming and macros (at least post scala-reflect) has been hamstrung by the “let’s think up some elegant setup from first principles” approach. I think that is entirely the wrong approach: a feature is nothing without use cases, and if you want a serious alternative to scala-reflect, you need to start with deeply understanding everyone’s use cases for macros, how you might want to support them, and then consolidating that into a coherent API.
If I was the one working on the project, I would start by taking a dozen or so popular OSS macro libraries and making sure their use cases are fully supported by-hook-or-by-crook, before even considering the elegance of the API. Until that happens, it’s not a “migration” issue, it’s just a “new thing is strictly worse than old thing” issue.
I wouldn’t ask anyone just-getting-started to work with Scala 3, unless they had Martin Odersky and team to teach them. The top priority for someone getting started is to just do what “everyone else” is doing, to minimize the number of irrelevant issues they may encounter while learning, and everyone else is very much not doing Scala 3. “Spark works on Scala 3 (in class at EPFL)” is very different from “Spark works on Scala 3 (at 2am on Saturday night when your biggest customer just called)”