얼마 전 회사 개발자 전용 슬랙 채널에 다음과 같은 이미지가 올라왔다. 깃허브(GitHub)에서 스타 100개 이상 획득한 프로젝트를 기준으로 버그 밀도(bug density) 통계를 낸 것이다.
그런데 그래프를 보고 있자면 직관적으로 봐도 고개가 갸우뚱해진다. 우리는 PHP와 JS를 주로 사용하는 회사인데 동료들도 그래프가 이상했는지 “PHP 프로젝트는 버그가 없다는 모양이네?ㅋㅋ”라거나 “JS는 사람들이 보고를 잘 안 하나 보다. 저럴 리가 없잖아” 같은 농담이 채널에 올라오곤 했다.
보통 C++, 자바(Java) 같은 언어가 버그가 적다는 인식이 있는데, 어떻게 이런 결과가 나왔는지 의문이 들었다. 동시에 누가 이런 조사를 대체 왜 했는지 궁금해졌다. 그래서 찾아낸 원본 글은 이 글의 제목보다 더 자극적인 제목이 붙어 있었다. 「정적 타입의 깨어진 약속(The broken promise of static typing)」.
대니얼 리브레로(Daniel Lebrero)가 쓴 이 글을 보면서 질문이 줄어들기는커녕 점점 늘어갔다. 이 글은 그런 질문에 답하기 위한 내 나름의 과정이다. 또한, 그 유명한 의식의 흐름 기법으로 글을 작성했기 때문에 읽기에 불편한 글이 될지도 모르겠다. 이 부분은 미리 양해를 구하고자 한다.
- 주의! 이 글은 어떠한 것도 보장해주지 않습니다. 자료 해석이나 글 내용 또는 인용한 자료 자체에 오류가 있을 수 있습니다. 자료의 인용이 글쓴이의 동의를 의미하지 않습니다.
타입 전쟁(Type War)
내 의문이 대니얼의 글에서 출발했듯이 대니얼의 글은 “엉클 밥(Uncle Bob)”으로 유명한 로버트 마틴(Robert C. Martin)의 글 「타입 전쟁(Type war)」에서 시작했다고 한다. 타입과 관련한 프로그래밍 언어의 역사를 소개해주는 글이라 혹시 여유가 있다면 한 번쯤 읽어보기를 권하고 싶은 글이다. 대충 요약하자면 다음과 같다.
- 정적 타입(static type)과 동적 타입(dynamic type) 언어에 관한 논쟁은 80년대와 90년대 C++의 정적 타입과 스몰토크(SmallTalk)의 동적 타입으로 거슬러 올라간다. (파스칼(Pascal)도 언급했지만 C/C++ 사용자였던 마틴은 그다지 경쟁자로 생각하지 않았던 듯)
- 케이퍼스-존스(Capers-Jones)가 언어별 프로그래머의 생산성에 관한 연구에서 스몰토크가 C++에 비해 훨씬 더 나은 생산성을 보여준다고 발표했다. 커뮤니티에서는 적어도 2배에서 많게는 5배 이상 차이가 날 것이라고 생각하는 사람이 다수였다. 이 와중에 C++ 개발자의 생산성이 더 좋을 거라고 말하는 사람은 없었다.
- 그때 IBM은 스몰토크를, Sun은 자바(당시엔 C++ Lite 수준)를 밀고 있었다.
- 이때 Sun의 자바 개발자들이 IBM의 스몰토크 개발자들을 상대로 이겼는데(아마도 논쟁이 있었던 듯) 그때 사용한 주 근거가 타입 안정성(type safaty)이었다. “이미 발사된 미사일에 탑재된 소프트웨어에 세그먼테이션(segmentation) 오류나 타입 예외(type exception)가 있으면 어떻게 할 것인가?”(이게 바로 ‘미사일 논쟁’)라는 식의 주장이 있었던 모양이다. 정확한 내용은 모르겠지만 여하튼 스몰토크가 대패했다. 심지어 마틴은 “이날 언어로서의 스몰토크는 죽었다”고 표현할 정도.
- 그 후 자바, 그리고 사촌격인 C#이 인터넷의 언어로 급부상. 20년 정도는 권좌에 있었다.
- 그 사이 스몰토크 프로그래머들은 미사일 문제에 대한 해법으로 TDD(Test Driven Development)를 제시했다(그땐 그 이름이 아니었다지만). 이를 통해 미사일이 목표물에 정확하게 도착할 것이라고 보장할 수 있게 되었는데, 심지어 컴파일러의 타입 체킹보다 훨씬 더 확실한 보장이 가능했다.
- 자바 진영도 TDD를 배우기 시작했다. 자바 개발자들 사이에 “유닛 테스트가 이미 다 확인해주는데 왜 자바의 타입 제약(type constraints)을 충족시키는 데 시간을 허비해야 하지?”라는 질문이 떠올랐고, 결국 많은 자바 개발자가 파이톤(Python)이나 루비(Ruby) 같은 동적 타입 언어로 전환하고 생산성이 매우 많이 향상되었다고 한다. 이게 2005년~2010년쯤 일어났던 일이다. 심지어 동적 타입 언어 개발자가 대체로 월급도 더 많았다고.
- 여전히 많은 개발자가 정적 타입 언어에서 동적 타입 언어로 전향하고 있는데, 이 전쟁은 어떻게 진행되고 어떻게 끝날까? 테스트 커버리지가 100%에 이른다면(충분히 가능) 정적 타입 체킹은 필요하지 않아질 것이므로 결국에는 스몰토크 또는 그를 위시한 동적 타입 언어가 이기지 않겠냐는 게 마틴의 의견.
대니얼은 정적 타입 언어를 사용하는 일부 사람이 마틴의 마지막 주장에 동의하지 않는 것을 보았고 정적 타입이 더 안전하다거나 유닛 테스트 대부분은 쓸모없다는 주장을 하는 것도 보았다. 대니얼이 해석한 그들의 주장은 이랬다.
“정적 타입 언어가 버그를 더 적게 만든다.”
프로그래밍 언어와 버그의 연관성
두 인자 사이에 연관성이 있는지는 정확히 알 수 없지만 일단 대니얼은 둘 사이에 어떤 연관성이 있을 것이라 가정한 듯하다. 그는 깃허브에 있는 프로젝트에서 “버그” 레이블이 붙은 이슈를 찾고 이를 언어별로 분류했다. 그 결과가 이 글 첫머리에도 첨부했던 아래 그래프이다.
참고로 원래 글에는 전체 저장소를 조사한 결과도 있고 스타 10개 이상 프로젝트를 조사한 결과도 있지만, 적어도 글쓴이는 스타가 많을수록 자료에 잡음이 덜하다고 생각했던 것 같으므로 여기서는 스타 100개 이상 프로젝트에 대한 결과만 싣는다. 어쨌든 그의 글은 정적/동적 타입 구분보다 결국은 언어의 단순성이 중요하다는 것으로 결론을 맺는다.
단순하다는 것은 이해하기 쉽고, 바꾸기 쉬우며, 유지 보수하기 쉽고, 더 유연하다는 의미이며 이는 곧 버그가 더 적다는 결론으로 이어진다고 말하면서 말이다. 그런데 보다 보면 조사 방법에는 조금 의문이 생긴다. 이걸 버그 밀도로 측정하는 게 맞는 건가. 보고되지 않은 버그가 많을 수도 있는 거 아닌가. 댓글을 보면 그렇게 생각한 건 나만이 아닌 것 같다.
이와 관련해 다른 연구 결과도 있다. 「깃허브의 프로그래밍 언어와 코드 품질에 대한 대규모 연구(A Large-Scale Study of Programming Languages and Code Quality in GitHub)」은 말 그대로 깃허브에 있는 프로젝트 728개를 대상으로 코드 품질과 언어 간의 상관관계가 있는지 연구한 자료다. 언어와 버그 생산에는 연관성이 있을까? 여기서는 언어별로 보면 경향성이 있다고 말한다.
연구 결과에 따르면 계수(Coefficient) 항목이 음수라면 버그를 평균보다 덜 유발한다는 의미라고 설명한다. 그러나 주의할 것이 있다. 비록 언어와 버그 생산 간에 통계적으로 유의미한 관계가 있는 것처럼 보이지만 전체 편찻값에서 “언어”가 차지하는 비율은 고작 1% 미만이므로 이를 과대평가하면 안 된다고 논문은 덧붙이고 있다.
이 자료를 처음 출발점인 “정적 타입과 동적 타입 언어의 차이”의 관점에서 보면 어떨까? 특이하게도 버그 유발성이 상대적으로 가장 높은 언어로는 정적 타입 언어인 C++이 있고, 반대로 가장 적은 언어로는 동적 타입 언어인 클로저(Clojure)가 있다. 전체적으로 보면 동적 타입 언어든 정적 타입 언어든 대략 절반 정도는 평균 이상, 나머지 절반 정도는 평균 이하를 기록하는 것으로 보인다.
이 결과를 나름대로 해석해보자면 언어 항목에서만 봐도 정적/동적 타입의 차이가 유의미하다고 생각하기 어려울 뿐 아니라 논문에서 밝혔듯이 전체로 보면 언어 자체가 굉장히 미미한 인자이므로 타입 체킹이 버그 생산 정도에 있어 유의미한 결과를 낸다고 보기는 어렵다고 생각한다.
프로그래밍 언어의 생산성
프로그래밍 언어의 속도만큼이나 오래됐으면서도 아직 결론이 없지만 여전히 뜨거운 주제가 아닐까 한다. 누군가 어떤 언어가 더 우월하다 혹은 열등하다는 주장을 하면 거의 반드시 반대되는 의견을 가진 사람이 나타난다. 언어 논쟁과 관련하여 글을 쓴 김에 이 주제와 관련한 연구는 없을까 하고 검색해보았다.
그래서 찾은 게 「소프트웨어 경제학 및 기능 포인트 측정법(
Software Economics and Function Point Metrics)」이다. 아마도 「타입 전쟁」에 언급된 그 자료의 최신 버전인 듯하다. 이 통계에서 소프트웨어의 기능 포인트(function point)를 투입한 시간(노동력)으로 나누어 각 프로그래밍 언어의 생산성을 측정한 것이다.
결과를 인용하기 전에 미리 말해두자면 분명 조사 방법이나 결과에 동의하지 않는 사람도 있을 것이다. 확실히 이 자료가 프로그래밍의 우위를 알려주지는 않는다고 본다. 그러니 그냥 참고 수준으로만 보도록 하자.
이 자료의 표 16을 보면 시간 대비 기능 포인트로 생산성을 측정한 것이다. 예상했겠지만 기계어, 어셈블리가 가장 생산성이 낮은데 놀랍게도 HTML이 79개 언어 중 생산성 나쁜 순으로 5위를 차지하고 있다. 자세한 내용은 위에 링크한 자료를 보도록 하고 여기서는 몇 개만 추려보겠다.
- HTML, 32.09 (언어, FP당 작업 시간)
- C, 26.27
- JS, 15.93
- C++, 12.70
- Go, 12.70
- 자바, 12.70
- PHP, 12.70
- Python, 12.70
- C#, 12.31
- Ruby, 11.31
- Erlang, 10.76
- Haskell, 9.84
- Perl, 9.46
- Objective-C, 7.85
- ASP.NET, 7.48
- 스몰토크, 6.88
- 평균 15.29
앞서 「타입 전쟁」에 등장했던 스몰토크가 다시금 생산성 통계에 등장했고 역시나 굉장히 높은 등급을 기록했다. 그러나 애초 “동적 타입과 정적 타입 언어의 생산성”의 차이라는 관점에서 보자면 두 분류의 언어가 엎치락뒤치락하는 형국으로 보인다.
참고로 이 통계 보고서에는 국가별 소프트웨어 생산성도 포함되어 있다(13쪽). 우리나라의 생산성이 미국 바로 위, 전체 52개국 중 29위라는 놀라운 결과가 나타났다. OECD 노동 보고서를 기준으로 노동 시간을 산출한 거라 실제로는 분모가 되는 노동 시간이 많이 축소된 거 아닌가 하는 의문이 있지만 말이다. 가장 높은 곳은 인도, 타이완, 멕시코, 중국, 페루 순이었고 가장 낮은 곳은 네덜란드, 독일, 노르웨이, 스웨덴 순이었다.
어쨌든 흥미로운 통계이고 믿고 안 믿고는 자유지만, 개인적으로는 겨우 통계 조사 결과 하나로 이 글처럼 누가 더 낫다 아니다는 말은 안 했으면 하는 바람이다.
그래서 누가 이기는데?
얼마 전 다시 정주행하고 있는 TV 프로그램에서 누가 이런 질문을 했다. “이소룡하고 타이슨하고 싸우면 누가 이기나?” 그때 강호동이 답하길 “그 날 컨디션 좋은 사람이 이긴다”고 했다. 사실 누가 이기고 지는 게 뭐가 중요한가. 어차피 측정할 수 없는 결과인데 내가 좋아하는 쪽을 응원하면 됐지.
내가 주력으로 사용하는 언어는 개발자들에게 늘 욕먹는 PHP와 자바스크립트이다. 앞서 인용한 통계에선 버그도 유발하고 생산성도 낮은 언어이기도 하다. 오늘 일부에선 세상에서 사라져야 할 프로그래밍 언어처럼 취급받는 PHP의 점유율은 얼마나 떨어졌는지 궁금해서 통계를 검색해보았다.
PHP7이 많이 좋아졌다지만 좀 늦게 나온 감이 있고, 최근 몇 년 사이엔 좋은 대안도 많았기에 점유율이 적잖이 떨어졌으리라 예상했다. 그런데 결과는 내 예상과 아주 달랐다.
PHP는 지난 7년간 시장 점유율이 10% 증가하여 83.1%가 됐다! 물론 이걸 두고 “PHP 짱!”같은 유치한 선언을 하려는 생각은 없다. 그저 역사적으로 볼 때 “기술적인 우월함이 시장에서의 우세함을 보장해주지는 못한다” 혹은 그 역과 같은 뻔한 사실과 함께 그러니 우월함이나 우세함은 별로 중요하지 않다는 말을 하고 싶을 뿐이다.
설령 기술적으로 뒤처지는 언어든 시장 점유율이 떨어지는 언어든 그게 무슨 상관인가. 내가 좋아하는 언어를 계속 사용하면 됐지.
원문: 코드쓰는사람
참조
- Robert C. Martin, 「Type war」
- Daniel Lebrero, 「The broken promise of static typing」
- Baishakhi Ray, Daryl Posnett, Premkumar Devanbu, Vladimir Filkov, 「A Large-Scale Study of Programming Languages and Code Quality in GitHub」
- Capers Jones, 「Software Economics and Function Point Metrics: Thiry years of IFPUG Progress」