라벨이 type checking인 게시물 표시

Flow vs TypeScript - 왜 나는 아직 타입스크립트를 쓰는가

나는 개인적으로 동적 타입 언어보다 정적 타입 언어를 선호한다. 아니 동적 타입 언어를 싫어한다. 정확히 말하면 동적 타입 언어이기에 생기는 실수에 의한 버그들과 그로 인해 사고에 걸리는 부하를 싫어한다. 그래서 웹 개발을 몇 년을 했지만 여전히 동적 타입 언어인 자바스크립트로 코딩하는 것은 싫어한다. 그 때문에 어지간히 간단한 일이 아니라면, 자바스크립트를 사용할 때 반드시 다른 툴을 붙여 정적분석을 한다.
 자바스크립트의 정적 분석을 위해 사용되는 도구는 크게 2가지로 나뉜다. 마이크로소프트에서 만든 타입스크립트와 페이스북에서 만든 플로우다. 한때는 구글이 타입스크립트를 기반으로 만든 AtScript라는 것도 있었지만, 이는 다시 TypeScript로 합쳐지면서 사라지게 되었다. 타입스크립트와 플로우는 둘 다 자바스크립트를 정적 타입 검사가 가능하도록 만들어주었다. 하지만 접근하는 방향은 완전 다른 방향으로 접근하였다.
 우선 타입스크립트는 2012년에 첫 버전이 나왔다. 타입스크립트의 목표는 자바스크립트로 변환되는 더 쓰기 편하고 안전한 언어를 만드는 것이었다. 어디까지나 자바스크립트로 변환되는 언어를 만드는 것이었기에 문법적 기반을 자바스크립트에 두었다. 다시 말해서 타입스크립트의 문법은 자바스크립트 문법의 슈퍼 셋이다. 자바스크립트의 문법을 기반으로 하여 그 위에 추가적인 기능을 더했다. 추가된 기능에는 class나 enum처럼 사용성을 올리기 위한 기능도 있고, private이나 타입 어노테이션 처럼 안전한 코드를 만들기 위해 추가된 기능도 있다.
 반면에 페이스북의 플로우는 새로운 언어를 정의하지 않는다. 플로우는 ECMAScript 6(a.k.a. ES6)의 타입 검증 도구일 뿐이다. 이미 타입스크립트의 많은 기능이 ES6에 표준으로 들어왔기 때문에 새로운 언어를 만들 필요가 없었다. 플로우는 새로운 언어를 정의하지 않기 때문에 이미 자바스크립트로 작성된 프로그램을 바로 분석할 수 있다. 타입이 모호한 경우에는 어노테이션을 추가하여 타입을 선…

[잡담] 대수적 자료형과 정적 타입 분석이 필요하다

트오세 출첵 이벤트 지금 무제한으로 수령되는 버그 있는데 버그 원인이 오타 다 pic.twitter.com/0YIS6YSIw1 — Enpi (@Enpi_) 2016년 1월 7일
 그랬다면 최소한 위와 같은 버그는 막을 수 있다.

Phantom type - 구체화 되지 않는 타입 추가하기

Phantom type은 받은 타입 파라미터 중에서 구조체의 선언에 기여하지 않는 타입 파라미터가 존재하는 타입을 말한다. 무언가 존재하는 것 같지만, 만져지는 실체가 없는 것이 유령 같다고 하여 phantom type이라고 불린다.

 내가 알기로는 Haskell에서 가장 먼저 도입된 것으로 알고 있다. Haskell이 phantom type을 사용하기 시작한 뒤로 파라메트릭 폴리몰피즘을 중시하며 강타입 타입 시스템을 가진 Scala나 Rust 같은 다른 언어에서도 사용된다.

 보통 phantom type을 사용하는 이유는 런타임 오버헤드 없이 컴파일 타임에 제약 조건을 추가하기 위해서다. phantom type에 사용된 타입 파라미터는 구조체의 값으로 사용되지 않기 때문에 구조체의 크기를 증가시키거나, 실행 시에 별도의 정보를 더 들고 다니지 않는다. 그저 컴파일 타임에 타입 체크하는 조건을 강화할 뿐이다.

이에 대한 좋은 예제가 rust by example에 있어서 가지고 왔다.1)

 위의 예제는 Length라는 구조체를 단위를 타입 파라미터로 받는 클래스로 선언하였다. 하지만 단위에 해당하는 Unit은 Length 구조체의 어떤 값으로도 사용되지 않는다. 따라서 Length 구조체의 크기는 f64의 크기와 같다.2) 하지만 Length<Mm>는 Length<Inch>와 다른 값이기 때문에 Length<Mm> 타입인 값과 Length<Inch> 타입인 두 값을 더할 수 없다.

1) 예제 코드는 Apache 2.0 라이센스로 배포되는 rust by example에 나오는 예제를 가지고 왔다.
2) rust는 구조체에 기여하지 않는 타입 파라미터를 만들 수 없어 PhantomData를 이용했다. PhantomData는 size가 0인 구조체이다.