ReScript

여러분은 이런 언어를 바란 적이 있습니까? JavaScript 같지만, 군더더기 없고, 훌륭한 타입 시스템을 갖췄고, 깔끔한 빌드 툴 체인을 갖추어, 여러분의 시간을 낭비하지 않는 언어를.

즉, 여러분은 방대한 JavaScript 생태계와 툴링 사이를 넘나들며, ReScript를 마치 오랫동안 알고 있던 것처럼 익힐 수 있을 것입니다!

ReScript는 JavaScript에 비판적인 거리를 두고 있지만 JavaScript의 중요성을 인정하는 사람들을 위한 언어입니다.

TypeScript와의 차이점

ReScript 팀은 TypeScript를 존중합니다. 또한 TypeScript는 JavaSript 생태계에 긍정적인 영향을 끼친다고 생각합니다. ReScript는 TypeScript와 같은 목표 일부분을 공유하지만, 몇 가지 중요한 뉘앙스에 관해서는 충분히 다른 점을 확인할 수 있습니다.

  • TypeScript의 목표는 JavaScript의 전체 기능을 포함하는 것입니다. 그러나 ReScript는 JavaScript의 기능 중 특별히 선별된 기능만 다룹니다. 예를 들어, 우리는 클래스보다 플레인 데이터 + 함수를 사용하고, 주의해서 다뤄야 하는 if 문과 가상 디스패치보다 깔끔한 패턴 매칭 을 사용합니다. 또한 문자열 오남용 대신, 적절한 데이터 모델링(배리언트)을 선호합니다.* JavaScript 수퍼셋은 시간이 지남에 따라 그 크기가 더 커질 뿐이지만, ReScript는 그렇지 않습니다.

  • 따라서, TypeScript의 타입 시스템은 필연적으로 복잡하고 피해 가야 할 함정이 많습니다. 잠재적으로 타입에 대한 조정이 필요하고 컴파일은 때때로 느립니다. 가독성 좋은 문서보다는, 매뉴얼 문서 관리 같은 느낌이 드는 번거로운 어노테이션을 필요로 합니다.

  • 반면, ReScript의 타입 시스템은:

    • 의도적으로 간단한 서브셋만 선정하여 더 쉬운 사용감을 선사합니다.

    • 타입 함정이 없습니다. 이른바, "사운드"한, 항상 정확한 타입 시스템입니다. 예를 들어, 어떠한 타입 값이 nullable이라고 표시되지 않으면, 해당 값은 거짓말을 하지 않고 undefined 값을 자동으로 통과시킵니다. ReScript 코드에선 null/undefined 에러가 없습니다.

    • 타입은 모두에게 동일합니다. 군더더기 없고, 이로 인해 중요하지 않은 이슈에 많은 시간을 쏟는 기회를 제공하지 않습니다.

    • 단순성과 큐레이션 덕분에 매우 정확하게 실행됩니다. ReScript는 JavaScript 개발을 위한 가장 빠른 컴파일러 및 빌드 시스템 툴체인 중 하나입니다.

    • 타입 어노테이션이 필요 없습니다. 여러분이 원하는만큼, 많거나 적은 어노테이션을 작성해도 됩니다. ReScript에 의해 타입은 올바르게 추론되고 정확성이 보장됩니다.

    • TypeScript로의 마이그레이션은 "넓이"가 우선으로 수행되는 반면, ReScript는 "깊이"가 우선인 방식으로 이뤄집니다. TypeScript는 모든 파일에 여기저기 타입 어노테이션을 추가하여 JavaScript 코드를 TypeScript 환경으로 변환할 수 있습니다. 그러나 이 행위로 개발자가 얼마만큼의 타입 안정성을 얻을 수 있을까요? 그리고 어떻게 측정할까요? 변환된 조각에서 활자 오류가 여전히 발생하거나 발생할 수 있습니다. 타입 오류는 여전히 코드 속을 비집고 들어올 수 있습니다. 그러나 ReScript에서는 순수한 ReScript 코드와 JavaScript 인터롭(interop) 기능의 코드로 명확하게 서로 경계선을 만듭니다. 변환된 ReScript 코드 모든 부분은 100% 깨끗합니다. ReScript는 컴파일을 통해 파일별로 JavaScript로 변환하고, 변환할 때마다 타입 안정성을 향상시킵니다.

* * 개발자가 완전한 JavaScript 코드를 작성해야하거나 상호 운용해야하는 경우, 이스케이프 해치를 제공합니다.

다른 장점들

앞서 언급한 간단하고 강력하고 빠른 타입 시스템 외에도 ReScript는 몇 가지 장점을 더 제공합니다.

JavaScript보다 빠릅니다

JavaScript는 오랜 기간에 걸쳐 재능있는 엔지니어들에 의해 최적화되었습니다. 그럼에도 불구하고 JavaScript 전문가들에게 마저 JavaScript의 성능을 제대로 활용하는 게 어려운 경우가 있습니다. 하지만 ReScript의 타입 시스템과 컴파일러는 다양한 Just-In-Time 최적화(히든 클래스, 인라인 캐싱, 디옵트 회피 등)를 잘 활용해 기본적으로 매우 자주 수행되는 코드를 작성하도록 자연스럽게 안내합니다.

널리 퍼진 격언 중에 빠른 JavaScript 코드를 작성하기 위해서는, "JavaScript 엔진의 우수한 최적화 휴리스틱을 이용할 수 있도록 마치 타입 시스템이 있는 것처럼 작성하라."라고 합니다. ReScript는 실제의 타입 시스템을 제공하고, 이 격언과 같은 장점의 코드를 작성해 기본적으로 최적화하기 쉬운 코드를 생성합니다.

사용하지 않는 코드를 훌륭하게 제거합니다

JavaScript 생태계는 패키지 의존성에 매우 민감합니다. 실제로 쓰이지 않는 엄청난 양의 코드가 최종 프로덕트 코드 번들에 들어가기도 합니다. 이 사용하지 않는 코드들은 로딩, 구문 분석, 인터프리터 속도에 영향을 끼칩니다. 그러나 ReScript는, 강력하게 만들어진 사용하지 않는 코드 제거 기능을 모든 단계에서 제공합니다.

  • 잘 설계된 타입 시스템과 순도 분석을 통해 함수와 모듈 수준의 코드 제거가 이뤄집니다.

  • ReScript가 자체적으로 사용하지 않는 코드를 정교하게 삭제하고 나면, 글로벌 수준에서 ReScript는 RollupClosure Compiler와 같은 번들링 도구를 사용하여, 사용하지 않는 코드 제거 과정에 친숙한 코드를 생성합니다.

  • ReScript 자체로 작성된 ReScript의 작은 런타임에도 동일하게 적용됩니다.

용량이 작은 JavaScript 결과물

Hello world ReScript 프로그램은 20 바이트 JavaScript 코드를 생성합니다. 또한, 표준 라이브러리 코드 조각은 정말 필요한 경우에만 포함됩니다.

개발시 빠른 반복 주기

ReScript의 빌드 시간은 JavaScript 생태계의 다른 정적 타이핑 환경보다 1 ~ 2배 빠릅니다. 워치 모드 중에 파일이 변경되면, 대부분의 빌드는 여러분이 에디터에서 터미널 탭으로 전환하기도 전에 완료됩니다(이는 2자리 밀리초와 맞먹습니다). 이렇게 빠르게 빌드가 완료되고 반영되는 환경은 개발자의 삶의 질을 높이고, 작업에 더 집중할 수 있게 해줍니다.

가독성을 고려한 결과물 & 훌륭한 인터롭(상호운용성)

다른 언어에서 컴파일 후 생성된 읽기 힘든 JavaScript 코드는 다음과 같은 곤란함이 있습니다.

  • 스택 추적이 암호 해석같이 까다롭고, 알 수 없는 변수 이름을 제공해 디버깅하기 어렵습니다.

  • 변환되기 전, 변환된 후의 언어가 일직선으로 매칭되지 않아 이해가 힘들어 배우기가 어렵습니다.

  • 어떤 런타임 성능 비용이 있는지 불분명하여 퍼포먼스 측정이 어렵습니다.

  • 손으로 작성 된 기존 JavaScript 코드와 통합하기 어렵습니다.

한편, ReScript의 JavaScript 결과물은 굉장히 읽기 편합니다. 이점은 배울 때 매우 중요한 점으로, 코드가 어떻게 컴파일되는지 이해하고 버그를 줄이기 쉽게 만들어줍니다.

이런 특성 덕분에 완전한 기능을 갖춘 JS 인터롭 시스템과 결합하여, 기존 JavaScript 코드 베이스에 자연스럽게 ReScript 코드를 삽입할 수 있습니다.

코드 구조 보존

ReScript는 하나의 소스 파일을 하나의 JavaScript 결과물 파일에 매핑합니다. 이는 번들러와 테스트 러너 같은 기존 도구의 통합을 쉽게 만듭니다. 빌드 설정을 크게 변경하지 않고 단일 파일로 ReScript를 시작할 수 있습니다. 각 파일의 코드 구조도 모두 보존됩니다.

결론

지금까지의 내용이 ReScript의 차별화된 장점을 충분히 설명하여, ReScript가 여러분들에게 더 친근히 다가갈 수 있길 바랍니다! ReScript의 플레이 그라운드에서 그 사용감을 확인해 보세요!