- 2000년대부터 2010년대 초까지 정적 타이핑의 인기가 하락했다가 2010년대 중후반에 다시 상승한 이유는, 유행이 아닌 정적 타입 시스템의 품질 향상
- 구덩이를 팔 때 종이로 만든 삽보다 맨손이 낫듯, 형편없는 정적 타입 시스템보다 동적 타입 시스템이 나음
- 초기 Java나 C++98 같은 과거 정적 타입 시스템은 nullable과 non-nullable 구분조차 못 하고 합타입이 없으며 타입명을 일일이 적어야 함
- TypeScript, Haskell, Swift, Rust 등 현대 타입 시스템은 null 구분, 합타입/유니온 타입, 타입 추론을 기본 제공
- IDE의 메서드 자동완성 보편화로 정적 타입에 입력한 정보가 오류 검사 외에 추가 생산성까지 가져옴
정적 타이핑 인기 변화에 대한 가설
- 정적 타이핑이 2000년대~2010년대 초에 인기가 줄었다가 2010년대 중후반에 다시 늘어난 현상은
프로그래밍이 유행 주도 산업이기 때문이 아니라 널리 쓰이던 정적 타입 시스템의 품질이 개선되었기 때문임
삽 비유 — 도구의 품질이 선택을 좌우
- 구덩이를 팔 때 삽이 쓸 만하다면 당연히 맨손보다 삽을 쓰겠지만,
유일하게 주어진 삽이 종이로 만든 것이라면 땅을 무의미하게 휘젓게 되어 차라리 맨손이 나음 - 동적 타입 시스템에서는 변수와 필드의 상태·내용을 전부 자기 머리로 직접 추적해야 하며,
컴퓨터는 돕지도 방해하지도 않아 맨손으로 파는 것에 해당 - 1990년대·2000년대 초에 흔했던 빈약한 정적 타입 시스템은 종이 삽과 같음
- nullable과 non-nullable 포인터 구분 같은 단순한 일조차 돕지 못함
- 곱타입(product type)만 있고 합타입(sum type)이 없음
- 타입명을 곳곳에 수작업으로 적어야 하는 부담 존재
BufferedReader bufferedReader = new BufferedReader(new FileReader(filename));같은 코드는 작은 재앙
현대 타입 시스템이 항상 제공하는 것
- TypeScript, Haskell, MyPy, Swift, Rust 같은 현대 타입 시스템과 대비하면 항상 아래를 제공
-
nullable과 non-nullable 구분
- Haskell은
Maybe t, TypeScript는T | null, Swift는T?, Rust는Optional<T>제공 - 타입 시스템이 null 체크가 필요한 모든 위치와 누락 여부를 쉽게 알려줌
- 실제로 런타임에서 null 포인터 오류를 거의 보지 못함
- Haskell은
-
합타입 또는 유니온 타입
- "잘못된 상태를 표현 불가능하게 만들기(Make invalid states unrepresentable)" 관행을 가능하게 함
- 여러 필드를 가진 상태 기계(state machine) 객체를 만들 수 있고, 각 필드는 시스템이 관련 상태일 때에만 존재
-
타입 추론
- 컴파일러가
let x = 5;를 숫자로 판단할 수 있으므로let x: number = 5;처럼 적을 필요 없음
- 컴파일러가
IDE 기능 확산이 더한 효용
- 메서드 이름 자동완성 같은 IDE 기능의 보편화가 정적 타입 시스템의 유용성을 키움
- 1990년대에는 Visual Studio의 Intellisense가 킬러 기능이었으나, 2020년대에는 거의 모든 IDE·에디터에서 유사 기능 이용 가능
- 정적 타입 시스템에 넣은 정보가 오류 검사용 외에도 추가 생산성 이점으로 이어짐
결론
- 좋은 동적 타입 시스템이 나쁜 정적 타입 시스템보다 나음
- 다만 이제는 과거보다 훨씬 나은 정적 타입 시스템을 보유