자바랑 자바스크립트랑 싸우면 누가 이길까?

정적 타입 언어와 동적 타입 언어의 생산성에 관하여

얼마 전 회사 개발자 전용 슬랙 채널에 다음과 같은 이미지가 올라왔다. GitHub에서 스타 100개 이상 획득한 프로젝트를 기준으로 버그 밀도(bug density) 통계를 낸 것이다.

버그 밀도 순으로 정렬한 언어. GitHub 스타 100개 이상 저장소 기준.

그런데 그래프를 보고 있자면 직관적으로 봐도 고개가 갸우뚱해진다. 우리는 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)가 언어별 프로그래머의 생산성에 관한 연구에서 SmallTalk가 C++에 비해 훨씬 더 나은 생산성을 보여준다고 발표했다. 커뮤니티에서는 적어도 2배에서 많게는 5배 이상 차이가 날 것이라고 생각하는 사람이 다수였다. 이 와중에 C++ 개발자의 생산성이 더 좋을 거라고 말하는 사람은 없었다.
  • 그때 IBM은 SmallTalk를, Sun은 Java(당시엔 C++ Lite 수준)를 밀고 있었다.
  • 이때 Sun의 Java 개발자들이 IBM의 SmallTalk 개발자들을 상대로 이겼는데(아마도 논쟁이 있었던 듯), 그 때 사용한 주 근거가 타입 안정성(type safaty)이었다. "이미 발사된 미사일에 탑재된 소프트웨어에 세그먼테이션(segmentation) 오류나 타입 예외(type exception)가 있으면 어떻게 할 것인가?"(이게 바로 '미사일 논쟁')라는 식의 주장이 있었던 모양이다. 정확한 내용은 모르겠지만 여하튼 SmallTalk가 대패했다. 심지어 마틴은 "이 날 언어로서의 SmallTalk는 죽었다"고 표현할 정도.
  • 그 후 Java, 그리고 사촌격인 C#이 인터넷의 언어로 급부상. 20년 정도는 권좌에 있었다.
  • 그 사이 SmallTalk 프로그래머들은 미사일 문제에 대한 해법으로 TDD(Test Driven Development)를 제시했다(그땐 그 이름이 아니었다지만). 이를 통해 미사일이 목표물에 정확하게 도착할 것이라고 보장할 수 있게 되었는데, 심지어 컴파일러의 타입 체킹보다 훨씬 더 확실한 보장이 가능했다.
  • Java 진영도 TDD를 배우기 시작했다. Java 개발자들 사이에 "유닛 테스트가 이미 다 확인해주는데 왜 Java의 타입 제약(type constraints)을 충족시키는 데 시간을 허비해야 하지?"라는 질문이 떠올랐고, 결국 많은 Java 개발자가 Python이나 Ruby 같은 동적 타입 언어로 전환하고 생산성이 매우 많이 향상되었다고 한다. 이게 2005년~2010년쯤 일어났던 일이다. 심지어 동적 타입 언어 개발자가 대체로 월급도 더 많았다고.
  • 여전히 많은 개발자가 정적 타입 언어에서 동적 타입 언어로 전향하고 있는데, 이 전쟁은 어떻게 진행되고 어떻게 끝날까? 테스트 커버리지가 100%에 이른다면(충분히 가능) 정적 타입 체킹은 필요하지 않아질 것이므로 결국에는 SmallTalk 또는 그를 위시한 동적 타입 언어가 이기지 않겠냐는 게 마틴의 의견.

대니얼은 정적 타입 언어를 사용하는 일부 사람들이 마틴의 마지막 주장에 동의하지 않는 것을 보았고 정적 타입이 더 안전하다거나 유닛 테스트 대부분은 쓸모없다는 주장을 하는 것도 보았다. 대니얼이 해석한 그들의 주장은 이랬다. "정적 타입 언어가 버그를 더 적게 만든다"

프로그래밍 언어와 버그의 연관성

두 인자 사이에 연관성이 있는지는 정확히 알 수 없지만 일단 대니얼은 둘 사이에 어떤 연관성이 있을 것이라 가정한 듯하다. 그는 GitHub에 있는 프로젝트에서 "버그" 레이블이 붙은 이슈를 찾고 이를 언어별로 분류했다. 그 결과가 이 글 첫머리에도 첨부했던 아래 그래프이다.

버그 밀도 순으로 정렬한 언어. GitHub 스타 100개 이상 저장소 기준.

참고로 원래 글에는 전체 저장소를 조사한 결과도 있고 스타 10개 이상 프로젝트를 조사한 결과도 있지만, 적어도 글쓴이는 스타가 많을수록 자료에 잡음이 덜하다고 생각했던 것 같으므로 여기서는 스타 100개 이상 프로젝트에 대한 결과만 싣는다. 어쨌든 그의 글은 정적/동적 타입 구분보다 결국은 언어의 단순성이 중요하다는 것으로 결론을 맺는다. 단순하다는 것은 이해하기 쉽고, 바꾸기 쉬우며, 유지보수하기 쉽고 더 유연하다는 의미이며 이는 곧 버그가 더 적다는 결론으로 이어진다고 말하면서 말이다.

그런데 보다 보면 조사 방법에는 조금 의문이 생긴다. 이걸 버그 밀도로 측정하는 게 맞는 건가. 보고되지 않은 버그가 많을 수도 있는 거 아닌가. 댓글을 보면 그렇게 생각한 건 나만이 아닌 것 같다.

이와 관련해 다른 연구 결과도 있다. "A Large-Scale Study of Programming Languages and Code Quality in GitHub"은 말 그대로 GitHub에 있는 프로젝트 728개를 대상으로 코드 품질과 언어 간의 상관관계가 있는지 연구한 자료이다. 언어와 버그 생산에는 연관성이 있을까? 언어별로 보면 경향성이 있다고 여기서는 말하고 있다.

다른 언어보다 버그를 적게 유발하는 언어도 있다.

연구 결과에 따르면, 계수(Coefficient) 항목이 음수라면 버그를 평균보다 덜 유발한다는 의미라고 설명한다. 그러나 주의할 것이 있다. 비록 언어와 버그 생산 간에 통계적으로 유의미한 관계가 있는 것처럼 보이지만, 전체 편차 값에서 "언어"가 차지하는 비율은 고작 1% 미만이므로 이를 과대평가하면 안 된다고 논문은 덧붙이고 있다.

이 자료를 처음 출발점인 "정적 타입과 동적 타입 언어의 차이"의 관점에서 보면 어떨까? 특이하게도 버그 유발성이 상대적으로 가장 높은 언어로는 정적 타입 언어인 C++이 있고, 반대로 가장 적은 언어로는 동적 타입 언어인 Clojure가 있다. 전체적으로 보면 동적 타입 언어든 정적 타입 언어든 대략 절반 정도는 평균 이상, 나머지 절반 정도는 평균 이하를 기록하고 있는 것으로 보인다.

이 결과를 나름대로 해석해보자면, 언어 항목에서만 봐도 정적/동적 타입의 차이가 유의미하다고 생각하기 어려울 뿐만 아니라 논문에서 밝혔듯이 전체로 보면 언어 자체가 굉장히 미미한 인자이므로 타입 체킹이 버그 생산 정도에 있어 유의미한 결과를 낸다고 보기는 어렵다고 생각한다.

프로그래밍 언어의 생산성

프로그래밍 언어의 속도만큼이나 오래됐으면서도 아직 결론이 없지만 여전히 뜨거운 주제가 아닐까 한다. 누군가 어떤 언어가 더 우월하다 혹은 열등하다는 주장을 하면 거의 반드시 반대되는 의견을 가진 사람이 나타난다. 언어 논쟁과 관련하여 글을 쓴 김에 이 주제와 관련한 연구는 없을까 하고 검색해보았다.

그래서 찾은 게 "Software Economics and Function Point Metrics"이다(아마도 Type war에 언급된 그 자료의 최신 버전인 듯하다). 이 통계에서 소프트웨어의 기능 포인트(function point)를 투입한 시간(노동력)으로 나누어 각 프로그래밍 언어의 생산성을 측정한 것이다. 결과를 인용하기 전에 미리 말해두자면, 분명 조사 방법이나 결과에 동의하지 않는 사람도 있을 것이다. 확실히 이 자료가 프로그래밍의 우위를 알려주지는 않는다고 본다. 그러니 그냥 참고 수준으로만 보도록 하자.

이 자료의 표 16을 보면 시간 대비 기능 포인트로 생산성을 측정한 것이다. 예상했겠지만 기계어, 어셈블리가 가장 생산성이 낮은데 놀랍게도 HTML이 79개 언어 중 생산성 나쁜 순으로 5위를 차지하고 있다. 자세한 내용은 위에 링크한 자료를 보도록 하고 여기서는 몇 개만 추려보겠다.

  • HTML, 32.09 (언어, FP당 작업 시간)
  • C, 26.27
  • JS, 15.93
  • C++, 12.70
  • Go, 12.70
  • Java, 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
  • SmallTalk, 6.88
  • 평균 15.29

앞서 Type War에 등장했던 SmallTalk가 다시금 생산성 통계에 등장했고 역시나 굉장히 높은 등급을 기록했다. 그러나 애초 "동적 타입과 정적 타입 언어의 생산성"의 차이라는 관점에서 보자면 두 분류의 언어가 엎치락뒤치락하는 형국으로 보인다.

참고로 이 통계 보고서에는 국가별 소프트웨어 생산성도 포함되어 있는데(13페이지) 우리나라의 생산성이 미국 바로 위, 전체 52개국 중 29위라는 놀라운 결과가 나타났다. OECD 노동 보고서를 기준으로 노동 시간을 산출한 거라 실제로는 분모가 되는 노동 시간이 많이 축소된 거 아닌가 하는 의문이 있지만 말이다. 가장 높은 곳은 인도, 타이완, 멕시코, 중국, 페루 순이었고 가장 낮은 곳은 네덜란드, 독일, 노르웨이, 스웨덴 순이었다.

어쨌든 흥미로운 통계이고 믿고 안 믿고는 자유지만, 개인적으로는 겨우 통계 조사 결과 하나로 이 글처럼 누가 더 낫다 아니다는 말은 안 했으면 하는 바람이다.

그래서 누가 이기는데?

얼마 전 다시 정주행하고 있는 TV 프로그램에서 누가 이런 질문을 했다. "이소룡하고 타이슨하고 싸우면 누가 이기나?" 그때 강호동이 답하길 "그 날 컨디션 좋은 사람이 이긴다"고 했다. 사실 누가 이기고 지는 게 뭐가 중요한가. 어차피 측정할 수 없는 결과인데 내가 좋아하는 쪽을 응원하면 됐지.

내가 주력으로 사용하는 언어는 개발자들에게 늘 욕먹고 있는 PHP와 자바스크립트이다. 앞서 인용한 통계에선 버그도 유발하고 생산성도 낮은 언어이기도 하다. 오늘 일부에선 세상에서 사라져야 할 프로그래밍 언어처럼 취급받는 PHP의 점유율은 얼마나 떨어졌는지 궁금해서 통계를 검색해보았다. PHP7이 많이 좋아졌다지만 좀 늦게 나온 감이 있고, 최근 몇 년 사이엔 좋은 대안도 많았기에 점유율이 적잖이 떨어졌으리라 예상했다. 그런데 결과는 내 예상과 아주 달랐다.

서버사이드 언어 시장 점유율 연간 통계

PHP는 지난 7년간 시장 점유율이 10% 증가하여 83.1%가 됐다! 물론 이걸 두고 "PHP 짱!"같은 유치한 선언을 하려는 생각은 없다. 그저 역사적으로 볼 때 "기술적인 우월함이 시장에서의 우세함을 보장해주지는 못한다" 혹은 그 역과 같은 뻔한 사실과 함께 그러니 우월함이나 우세함은 별로 중요하지 않다는 말을 하고 싶을 뿐이다. 설령 기술적으로 뒤처지는 언어든 시장 점유율이 떨어지는 언어든 그게 무슨 상관인가. 내가 좋아하는 언어를 계속 사용하면 됐지.

참조

  1. 엄청 재밌게 잘 읽었어요. 예전에 PHP가 이유없이 싫었는데 여러 가지 언어를 사용해 보니 생각이 바뀌었어요. 그냥 언어는 도구니까 필요한 도구를 필요한 일에 잘 사용하면 되는 것 같습니다. 그리고 PHP는 충분히 사용할 만한 도구라고 생각해요.

    1. 그렇죠. 어떤 언어든 부족한 부분이 있을테고 어쩌면 PHP는 그게 좀 더 많을 지도 모르지만 그렇다고 사라져야 마땅한 건 아니라고 생각합니다.
      개인적으로 언어 근본주의자들은 일단 걸러요. 그런 분들은 한국어는 왜 쓰나 몰라요. 영어가 훨씬 생산적일텐데요.

  2. 흥미로운 내용이었습니다. 미사일 논쟁 부분이 관심 있는데 관련 자료 찾기가 힘드네요.. 혹 참고하신 링크자료 같은게 있다면 요청드릴수 있을까요?

    1. 미사일 논쟁에 관한 부분은 저도 엉클밥의 블로그에서 본 게 전부라 정확한 개요는 알지 못합니다. 물론 그 블로그 글은 본문에 링크해두었고요.
      궁금해하셔서 저도 호기심이 생기는데 혹시 더 상세한 자료를 발견하시게 되면 저한테도 알려주세요. ^^

  3. 개발자님의 블로그는 프론트엔드개발자를 꿈꾸는 저에게 많은 동기부여가 되고있습니다.
    제가 원하는 꿈을 이루기까지 지치지 않을 수 있도록 도움이 되주셔서 감사합니다.
    공부하다가 힘들 때, 또 들러 좋은 글을 보며 쉴 수 있도록 하겠습니다.
    조금 늦었지만 새해 복 많이 받으십시오.
    (ps: 블로그 폰트가 너무 예쁩니다^^)

    1. 저한테도 더 열심히 살아야겠다는 동기 부여가 되는 말씀입니다. 새해 복 많이 받으세요!

  4. 의식의 흐름 기법이라기엔 너무 잘 정돈되었는데요? 흥미진진하게 읽었습니다.
    제 개인적으로는 2013년 이전으로는 C/C++를 주로 사용하고, 그 이후로는 Python, PHP를 사용하고 있습니다. C계얼의 언어를 쓰다가 파이썬을 쓰기 시작했을 때 저는 '구원받았다'는 느낌을 받았어요. 파이썬 자체가 더 쉽게 쓸 수 있기도 했지만, 정적 타입 특유의 꼬장꼬장함이 너무나 부담스러웠기 때문이었던 걸로 기억합니다. 뭐, 반면 처음 파이썬 쓸 땐 너무 자유롭게 나가다 중요할 때 삐끗하곤 했지만요 🙂

    1. 제 궁금증을 해결하려는 목적으로 쓴 글이다보니 다소 미흡한 부분도 있었을텐데 감사합니다. ㅎㅎ 저도 처음 배운 언어가 C였는데 그래서 Perl이나 PHP를 처음 봤을 때는 신세계를 만난 거 같더라고요.

  5. 좋은 글 잘 봤습니다~ 감사합니다^^
    예전에 조건문 중 if, switch 둘 중 뭐가 더 빠르다 라고 해서 테스트 해봤던 일이 생각나네요

    결과는 상황에 맞게 사용하는게 가장 좋다라는 결과를 얻었습니다!!

    언어도 마찬가지 라고 생각하네요^^
    환경에 맞는 언어를 사용하는게 가장 좋은거 같아요

댓글을 남겨주세요