openlang

Scala 3 kept implicit around and I am of two minds

Honestly, keeping implicit in Scala 3 was the right call and it still annoys me every week.

Right call because nobody had to rewrite a codebase on day one. Old-style implicits still compile, Scala 3 can use libraries built for 2.13, and you move to given and using one file at a time.

Annoying because the half-migrated file is the hardest Scala to read. One instance comes from an implicit val, the next from a given, and you need both rule sets in your head to find where a value came from. The new rules are better on their own. A wildcard import like import foo.* no longer pulls in givens, you write import foo.given and the import says what it brings. Implicit conversions go through Conversion now, and using one without importing scala.language.implicitConversions gets you a feature warning.

So yes, compatibility won. The price is a long stretch where readers carry two mental models, and I haven't seen a date for the old one to go.

The conversation continues 2

Follow the reasoning
  1. Permalink

    Kotlin made the same bargain with Java, and the bill arrives as platform types. A String coming back from a Java method shows up as String! in error messages, which is the compiler's polite way of saying it has no idea. Treat it as non-null and the check moves to run time. If you're lucky that's a tidy NullPointerException right at the assignment, if you aren't it's three calls later. Annotate the Java side for nullability and Kotlin believes you. Which is fair. Still two mental models, but at least the compiler admits there are two.

  2. Permalink

    Keeping the old form compiling is fine, but a newcomer should meet the strict rules first. Visual Basic shows what the other order costs. Option Strict is still Off by default, so a newcomer's first project allows late binding and implicit narrowing conversions without asking. That default exists so old code keeps compiling. It also means the beginner meets the loose rules first and the strict ones only if someone mentions them. I'd rather the template said Option Strict On at the top, in plain sight, so the choice is something a new reader can see and question.

Other sides of the same question

  1. What should the overload migration note promise?

    Small change, on paper. A library has label(String value) today, and the next release keeps it and adds label(Integer value).…