openlang

Scala 3가 implicit을 남긴 건 반만 반갑다

솔직히 Scala 3에서 implicit을 남긴 건 맞는 결정이었어. 근데 그래도 매주 짜증 나.

맞는 결정인 이유는 첫날부터 코드베이스를 다시 쓸 필요가 없었다는 거야. 옛 방식 implicit은 그대로 컴파일되고, Scala 3는 2.13용으로 빌드된 라이브러리를 쓸 수 있고, given과 using으로는 파일 하나씩 옮기면 돼.

짜증 나는 이유는 반쯤 옮긴 파일이 제일 읽기 힘든 Scala라는 거야. 인스턴스 하나는 implicit val에서, 다음 건 given에서 오니까 값이 어디서 왔는지 찾으려면 규칙 두 벌을 다 머리에 넣고 있어야 해. 새 규칙만 놓고 보면 더 나아. import foo.* 같은 와일드카드 import는 이제 given을 안 끌어와서 import foo.given이라고 써야 하고, 그러면 import가 뭘 가져오는지 스스로 말해. 암묵적 변환은 이제 Conversion을 거치고, scala.language.implicitConversions를 import 안 하고 쓰면 기능 경고가 떠.

그러니까 호환성이 이긴 건 맞아. 대가는 읽는 사람이 머릿속 모델 두 개를 오래 들고 다녀야 한다는 거고, 옛 방식을 없앨 날짜는 아직 못 봤어.

이어지는 대화 2

서로의 근거를 따라
  1. 고유 링크

    Kotlin도 Java와 같은 거래를 했고, 청구서는 플랫폼 타입으로 날아와요. Java 메서드에서 돌아온 String은 오류 메시지에서 String!로 보이는데, 컴파일러가 전혀 모르겠다는 말을 공손하게 하는 방식이에요. 그걸 non-null로 다루면 검사는 런타임으로 밀려요. 운이 좋으면 대입하는 자리에서 깔끔한 NullPointerException이 나고, 운이 나쁘면 호출 세 번 뒤에 나요. Java 쪽에 nullability 애너테이션을 달면 Kotlin은 그 말을 믿어 줘요. 공평하죠. 머릿속 모델이 두 개인 건 그대로지만, 적어도 컴파일러가 두 개라고 인정은 해요.

  2. 고유 링크

    옛 형식이 계속 컴파일되는 건 괜찮지만, 처음 배우는 사람은 엄격한 규칙부터 만나야 합니다. 순서가 반대일 때 무엇을 치르는지는 Visual Basic이 보여 줍니다. Option Strict는 지금도 기본값이 Off라서, 처음 만든 프로젝트에서 늦은 바인딩과 암시적 축소 변환이 아무 확인 없이 허용됩니다. 그 기본값은 옛 코드가 계속 컴파일되도록 남아 있는 것입니다. 하지만 그 때문에 초보자는 느슨한 규칙을 먼저 만나고, 엄격한 규칙은 누가 말해 줘야만 알게 됩니다. 저는 템플릿 맨 위에 Option Strict On이 눈에 보이게 적혀 있으면 좋겠습니다. 그래야 새로 읽는 사람이 그 선택을 보고 의문을 품을 수 있습니다.

같은 질문의 다른 갈래

  1. 오버로드 추가 안내는 어디까지 약속해야 할까요?

    겉으로 보기엔 작은 변경이에요. 지금 라이브러리에 label(String value)가 있고, 다음 릴리스는 이걸 그대로 두면서 label(Integer value)를 추가해요. 이미 컴파일된 호출 코드는 괜찮아요. 클래스…