static typed language 와 dynamic typed language에 대한 생각들


- static typed language 는 컴파일시 더 많은 오류를 잡아준다.


static typed language 중 haskell 같은 언어는 ADT, GADT 를 통해

dynamic typed language는 물론이고 기존 c++/java/c# 등에서도

runtime에 체크해야 했던 부분들을 컴파일 타임에 검증해준다.

덕분에 코드가 간단해지고 명확해진다.

개인적으로 정말 좋아하는 feature 이다.


=> 1. 그래도 테스트는 필요하다.

2. ADT, GADT등을 사용한다고 테스트 항목이 줄어드는 것은 아니다.

테스트는 유효한 입력에 대해서만 한다.

3. ADT, GADT를 사용해서 절대 발생할수 없는 버그들이 dynamic typed

language에서는 발생한다.

하지만 dynamic typed laugage는

- 언어 구조가 훨씬 간단하여 버그도 줄어든다.

C++의 복잡한 템플릿 및 소위 디자인 패턴의 수많은 패턴들이

dynamic typed language에서 얼마나 간단하게 구현되는지

보면 알수 있다(dynamic typed language에서는 더이상 패턴이 아니다).

이로 인해 개발시간이 빠르며 버그 캐치도 빠르다.

- interactive development - 개발환경이 interactive하여 버그도 훨씬 빠르게 수정할수 있다.


- static typed language 는 type level programming 으로 추상화하기 쉽다


type 관련 오류를 컴파일러가 캐치해줌으로 type level에서 개발이 가능하며 이로 인해

추상화가 훨씬 쉽다. 즉 컴파일만 되면 어느정도 안심하고 다음 단계의 추상화가 가능하다.


=> 이부분은 환상이다. 컴파일이 되고 여전히 미심쩍다. 테스트가 필요하다.

- static typed language 는 비교적 더 적은 문서화가 필요하다


어떤 코드든지 문서화는 필요하다.

하지만 static typed language 는 코드에 type정보들이

기술됨으로 비교적 문서화할 정보가 줄어들거나 툴을 통해 자동 문서화 하기 쉽다.


=> 그런데 결국 문서화는 필요하다.

haskell 의 대부분의 라이브러리는 문서화 없이 어떤 것도 사용할 수 없다.

단지 문서화 양을 일부 줄이는 대가로 static typed 를 선택하기엔 얻는거 대비

잃는 것이 너무 크다.

- static typed language는 유지보수가 좋다.


data structure를 변경한 경우 해당 data 를 참조하는 부분은 모두 컴파일 타임에 오류가 발생한다.

따라서 관련 코드를 변경한후 컴파일이 정상적으로 되면 data structure 변경에 대한 수정작업들이

거의 완료되었다고 생각할 수 있다.


=> 그래도 테스트는 필요하다. 결국 test-case를 돌려봐야 하며

그렇지 않으면 프로그램 퀄러티는 떨어진다.

결국 큰 이점은 아니다.

- static typed language 는 가독성이 좋다.

문서화가 부족하더라도 코드에 type정보들이 기술됨으로 가독성이 훨씬 좋다.

가령 어떤 dynamic typed language에서 스캔코드를 가져와서 esc 가 눌려졌는지

확인하고자 한다면


is_equal(scancode(get_scancode(), 여기에뭘넣어야하는지?))


1. 문서 확인. 해당 부분 못찾음

2. 소스에서 함수 정의를 찾아봄

코멘트 없음

함수안에서 또 다른 함수를 부름.

또 쫓아감.

함수 정의

def is_equal_scancode(scancode, scancode)

return call_another_func_for_equl_scan_code(scancode, scancode)

=> 위에도 잠시 언급한 것처럼 이러한 가독성을 높이기 static type 을 선택한다면

많이 과장해서 벼룩한마리 잡자도 집에 불지르는 것과 비슷한 행동일것이다.


다음의 C++코드를 보자.

class GameObject;

class Player : GameObject;

class Enemy : GameObject;


shared_ptr<GameObject>

shared_ptr<Player>

shared_ptr<Enemy>

shared_ptr<Player> 와 shared_ptr<Enemy>는

더이상 shared_ptr<GameObject> 와 is-a 관계가 아니다.


이를 해결하고자 또 트릭성 코드를 사용해야 한다.


이건 GC 사용유무와 관계가 없다.

static typed 의 복잡성을 얘기하는 것이다.


static typed 가 확실히 어느정도 단순한

데이터 구조는 가독성을 높여준다.


그런데 어느정도 이상 복잡해지면 결국 잘 쓰인 문서가 필요하다.

- static typed language 는 미래의 언어이다.


여러 type 이론들이 발전하게 되면 지금 가지고 있는 단점들을 개선하게

될것이고 기존 dynamic typed language가 가지고 있는 장점들도 모두 흡수

하게 될것이다.현재 static typed language 에서 많이 쓰이는 타입 추론,

다형성이 좋은 예이다.


=> 지금의 지식으로 미래는 모른다. 지구가 둥글다는게 말이 되는가?

그리고 나는 지금 현재를 살고 있다.


- static typed language는 dynamic typed language 에 비교해서 성능이 좋다.


프로그램 코드에 기술된 타입정보들과 여러가지 제약(ex. const, pure function)들은

컴파일시 더 빠른 코드를 생성하기에 유리하다.


=> 맞다. 


- dynamic typed language 는 코딩 -> 테스트 주기가 빠르다.


static typed languge 는 컴파일 시간이 비교적 오래 걸린다. 특히 C++의

템플릿코드가 포함된 컴파일/링킹 타임은 끔찍하며 유니티 빌드, 분산빌드 등

많은 노력을 해도 여전히 끔찍하다.


가끔 빌드, 특히 링킹 타임을 줄이기 위해 검색하다 보면 누군가가 링킹타임이

수십초가 걸려서 도움을 바란다는 질문글에 수십초면 날라 다니는 거라고

하며 본인은 최대한 linking time을 줄여도 지금 수분씩 걸린다는 답글을 쉽

게 볼수 있다.


즉 코드 한줄 수정해서 테스트하는데 수분씩 걸린다는 것이다.


이를 보완하는 것이 TDD 등이 있지만, TDD보다는 바로바로 코드를 테스트 해 볼수

있는 것이 훨씬 생산성이 좋다.


- hot reloading


dynamic typed language 처럼 컴파일 속도가 빠르다 해도 웹서버, 게임 처럼

프로그램 로딩이 오래 걸리는 프로그램의 경우 테스트 싸이클이 길어지는데

이를 위한 것이 hot reloading이다.

C++ 같은 경우 이슈가 많고 haskell같은 경우 충분히 잘되지만 아무래도 lisp 처럼

함수단위로 compile되서 실제 이미지에 업데이트 되는 환경보다는 번거롭다.

(hot reloading 되는 시점의 코드가 변경될때마다 수정해줘야 한다)

절대적일수는 없지만 아무래도 dynamic typed language가 이러한 부분에서는 유리하다.