1월, 2016의 게시물 표시

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

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

reflection과 introspection

Reflection은 실행 시간에 객체의 메타 데이터에 접근하여 원래라면 접근할 수 없는 타입 정보, 프로퍼티, 멤버 함수 등을 수정하는 행위를 말한다. 이는 프로그래머에게 기존의 제약을 넘어서 더 많은 것을 할 수 있게 해준다.
 Reflection 중 실행 시간에 메타 데이터를 읽는 기능만을 구분해서 introspection이라고 부르기도 한다. 하지만 reflection이라고 하면 당연히 introspection을 포함해서 말하는 것이기 때문에, 특별한 이유가 없으면 그냥 전부 reflection이라고 부르기도 한다.

 Reflection은 매우 유용한 도구로 보인다. 하지만 개인적으로 좋아하는 기능은 아니다. 오히려 싫어하는 기능이다. Reflection이 주는 힘은 너무 과한 힘이고 대부분의 경우 득보다 실이 더 많다. Reflection은 기본적으로 실행 시간에 실행되기 때문에 컴파일 타임에 당연히 잡힐 문제를 잡지 못한다. 게다가 컴파일러가 코드 최적화를 하지 못하기 때문에 성능이 느려지는 등 여러 문제를 일으킨다.
 그래서 reflection을 사용해야 하는 일이 생기면, 일단 다른 방법이 없는지 알아보고, reflection을 사용하지 않을 방법이 알아보고, 그래도 방법이 없을 때만 사용한다. 지금까지 그래야 했던 경우는 디펜던시 인젝션을 하는 라이브러리를 이용하거나, 디버깅 로그를 찍기 위해 보통은 접근할 수 없는 정보가 필요하거나, 임의의 객체를 시리얼라이즈를 하는 함수를 만들거나, 내가 건드릴 수 없는 라이브러리에서 제공한 객체의 정보를 가져오는 등의 일이었다. 전부 수정할 수 없어서 어쩔 수 없이 쓴 경우다.

[ECMAScript 6] class 선언하기

JavaScript는 훌륭한 객체 지향 언어다. 하지만 프로토타입 기반 객체지향이라는 독특한 개념과 특유의 verbose한 문법 때문에 다른 언어에서 넘어온 사람들은 쉽게 적응하지 못하였고, 객체 지향스럽지 않은 코드를 작성하였다. 그럼에도 프로토타입은 다른 객체 지향 언어가 제공하는 class에 비해서 더 유연한 확장성 지원하기 때문에 많은 JavaScript 개발자들은 class가 필요 없다는 입장을 고수해왔다.
 하지만 프로토타입이 코드를 verbose 하게 만들고, 가독성을 떨어뜨린다는 주장은 꾸준히 제기되었고, 결국 ECMAScript 6에 드디어 class 키워드가 추가되어 보다 쉽게 객체 지향적 코드를 작성할 수 있게 되었다.  여기서 중요한 것은 class 키워드가 ES6에 추가되었다고 해서 클래스 기반 객체지향이라는 개념이 추가된 것은 아니라는 것이다. ES6도 여전히 프로토타입 기반의 객체 지향 언어이다. class는 프로토타입 기반 객체를 만드는 syntactic sugar일 뿐이다. 즉, 위와 같은 코드는 ES5를 기준으로 보면 아래와 같이 해석된다.1)class 스타일의 간결성과 prototype의 유연성을 동시에 갖기 위한 선택이었다. 1) 완전히 일치하는 것은 아니다. ES5에는 생성자로 쓸 수 없는 함수가 존재하지 않기 때문에 method를 완벽히 재현할 수 없다.

[ECMAScript 6] property 선언하기

property란 사용하는 코드는 member data에 접근하듯이 사용하지만 실제로는 함수가 호출되도록 하는 프로그래밍 언어의 기능을 말한다. C#, Python, Ruby 등 객체를 중요시하는 언어에는 대부분 존재하는 기능이며 당연히 기존의 JavaScript에도 있었다. 하지만 Object.defineProperties 함수를 이용해야 해서 코드가 복잡해진다는 문제가 있었다.  ES6에서는 property를 쉽게 선언할 수 있는 문법을 도입하였다. 메소드의 이름 앞에 get이나 set을 붙이는 것만으로 property를 선언할 수 있다.

[ECMAScript 6] method 선언하기

ECMAScript 5에는 메소드에 해당하는 개념이 없었다. 그저 함수가 first-class citizen이기 때문에 객체의 멤버변수로 함수를 할당하는 방식으로 메소드를 만들었다.

 ECMAScript 6에는 method를 만들기 위한 문법이 추가되어 메소드를 선언할 수 있게 되었다.

 이는 크게 보면 ES5에서 사용하던 함수를 멤버변수에 할당하는 방식과 다를 것 없다. 하지만 사소한 부분에서 약간 다르다.  메소드는 이름을 가지지만 new를 통해서 객체를 만들어낼 수 없다.

 이는 메소드만이 가지는 특징이다. 일반적인 함수는 모두 new를 통해 객체를 만들어낼 수 있다. 반면에 람다 함수는 new를 통해서 객체를 만들 수 없지만, 이름을 가지지 않는다.

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

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