본지 12월 특집을 읽고 오랜만에 이런 저런 생각을 할 수 있는 시간을 갖게 됐다. 한참 게을러져 있던 필자에게 많은 도움을 준 유익한 글이었다고 생각한다. 그 글을 통해 알게 된 새로운 사실과 결론에 대해 일말의 의심도 갖지 않는다. 다만 특집을 쓴 김재우 씨가 의도한 바와는 다르게 자바와 C# 같은 좋은 기술이 필요 이상으로 평가 절하될 소지가 있을 것 같아 자바와 C#을 좋아하는 개발자의 입장에서 약간의 변호를 하고자 한다. 부디 필자의 짧은 지식으로 쓴 이 글이 지난 특집의 의미를 조금이라도 훼손하지 않기를 바라며 조심스럽게 글을 시작한다.자바는 과연 어려운 언어인가자바는 분명히 C++에 비해 상대적으로 쉬운 언어지만, 프로그래밍 언어라는 것 자체가 쉬운 것이 아니라는 점에서 '자바가 쉽다'라는 말은 엄밀히 따져보면 틀린 말일 수 있다. 하지만 이러한 전제 없이 무작정 '자바는 어려운 언어다'라고 하면 오해의 소지가 있기 때문에 조금 더 이야기를 해보고자 한다.우선 교육기관에서 처음 프로그래밍을 공부하는 학생들에게 자바를 가르치는 것에 대해 살펴보자. 자바는 쉽지 않기 때문에 학생들에게 프로그래밍을 가르치기 위해 자바를 선택하는 것이 과연 적절하지 못할까? 다음 코드는 지난 특집에도 나온 바 있는 가장 간단한 코드이다.public class Test { public static void main(String[] args) { System.out.println("Hello, World"); }}만약 자바를 가르치는 것이 목적이라면 설명하기 어려운 예제지만, 자바를 가르치는 것이 목적이 아니라 프로그래밍을 가르치는 것이 목적이라면 C 언어 Hello World 예제만큼이나 쉽다.public class Test { public static void main(String[] args) { // 여기에 프로그램을 작성하면 됩니다 System.out.println("Hello, World"); }}이렇게 써 놓은 다음, "System.out.println();은 화면에 뭔가를 출력하는 기능을 하고 그 줄 앞뒤에 있는 문장은 반드시 써줘야 하는 부분이다"라고 설명하면 바로 다음 진도를 나갈 수 있다. public이 뭔지 static이 뭔지는 중요하지 않다. 자바를 가르치는 것이 아니라 프로그래밍을 가르치는 것이 목적이기 때문이다(이는 영어 공부를 할 때에도 마찬가지다. 영어 독해나 회화 등을 잘하기 위해서 영문법을 공부할 필요는 없다. 동사·관사·명사가 뭔지 따위는 몰라도 된다는 얘기다). 다음 진도로 바로 제어문, 선언문 등 문장에 대한 설명과 자료형(Value Type만), 수식에 대한 설명 등을 진행할 수 있다. String은 Value Type이 아니기 때문에 곤란하다고 생각할 수 있지만 String class는 Immutable이기 때문에 한동안 Value Type으로 취급해도 아무 문제없다. 이름 공간(package, import), 객체지향(class, interface, implements, extends), 가시성(public, private, protected...) 등에 대한 이해 없이 바로 절차 지향적 프로그래밍을 시작할 수 있고(물론 "지금 여러분은 절차 지향적 프로그래밍을 배우고 있습니다"라는 설명을 할 필요조차 없다), 이 상태에서도 풀 수 없는 문제는 사실상 없다. java.lang.* 이외의 이름 공간에 존재하는 API를 사용하기 위해서는 import 명령을 사용해야 하는데 이건 C에서 #include 전 처리기 명령을 이용해 표준 라이브러리의 헤더 파일을 읽어오는 것과 같은 식으로 설명할 수 있다. #include와 import가 다르다는 것은 Namespace 개념을 배울 때에, 또는 프로그래밍이 아닌 자바라는 프로그래밍 언어를 배울 때에 설명하면 아무런 문제가 없다.즉, C를 갖고 프로그래밍 공부를 하나 자바를 갖고 프로그래밍 공부를 하나 비슷하다는 뜻이다. 그렇다면 굳이 C로 프로그래밍 공부를 한 다음 자바나 C#과 같은 실무에서 주로 쓰이는 언어에 대한 적응 과정을 거치는 것보다는 애초부터 자바나 C# 등으로 공부를 하는 것이 더 효율적일 수 있다. 많은 교육기관들의 문제는 프로그래밍을 배워야 할 학생들에게 '자바 프로그래밍 언어'를 가르친다는 것이지, 자바를 선택한다는 것 자체가 문제인 것은 아니라고 생각한다.프로그래밍 언어가 어려운 이유교육 기관에서 자바나 C#을 가르치는 것에 대한 이야기는 이쯤에서 접고, 순수하게 '자바라는 언어는 쉬운가?'하는 문제에 대해 논의해 보자. 이 짧은 물음에 답을 하는 것은 생각보다 쉽지 않다. 그 전에 선행돼야 할 질문이 있기 때문이다. 바로 '무엇이 프로그래밍 언어를 어렵게 만드는가?'이다.프로그래밍 언어를 처음 공부하는 사람이 많은 시간을 보내는 이유는 언어의 문법, 그 자체를 외우는 데 시간이 걸리기 때문이 아니라 언어에 내재돼 있는 개념(Abstraction)을 이해하는 데에 시간이 걸리기 때문이다. 일단 한가지 이상의 프로그래밍 언어를 익힌 사람이 새로운 언어를 익힐 때엔 훨씬 더 수월한 이유는 모든 프로그래밍 언어가 일련의 공통적인 개념을 공유하고 있기 때문이다.베이직을 공부한 사람이 C++를 공부하는 것 보다 C를 공부한 사람이 C++을 공부하는 것이 상대적으로 쉽다. 그 이유는 C라는 언어에 내재된 개념들이 베이직이라는 언어에 내재된 개념에 비해 C++과 상대적으로 많은 부분을 공유하고 있기 때문이지, 결코 C와 C++의 문법이 비슷해서가 아니다. C에 익숙한 프로그래머가 C++를 배우면 한동안 C 스타일의 코딩을 계속 하는 것을 볼 수 있다. 그 이유는 C++에서 추가된 문법들은 외웠으나 C++라는 언어에 내재된 개념들(예를 들어 객체지향)을 익히지 못했기 때문이다.일례로 비주얼 베이직 프로그래머가 비주얼 베이직 닷넷을 배우는 것은 어렵지만 자바 프로그래머나 C# 프로그래머(특히 C# 프로그래머)가 비주얼 베이직 닷넷을 배우는 것은 상대적으로 쉽다. 문법만을 보면 비주얼 베이직과 비주얼 베이직 닷넷이 가장 흡사하지만 비주얼 베이직 닷넷은 자바나 C#에 존재하지만 비주얼 베이직에는 존재하지 않는 개념(Abstraction)을 많이 갖고 있기 때문이다. 언어의 문법이 비슷해서 얻을 수 있는 이점이라고는 다만 친숙한 느낌을 줄 수 있다는 것뿐이다(사실 친숙한 느낌 자체도 학습 동기 유발이라는 관점에서 중요할 수 있다).다시 말해서 많은 개념을 내재하고 있는 프로그래밍 언어는 상대적으로 배우기 어렵다. 그리고 서로 비슷한 개념을 내재하고 있는 두 언어가 있다면, 그 개념을 표현하기 위한 문법이 간결하고 직관적일수록 배우기 쉬운 언어라고 할 수 있을 것이다. 어떤 언어가 직관적인가 하는 문제는 언어를 배우는 사람의 습관이나 사용하는 언어 등에 크게 의존적일 것이므로 제외하고 생각하도록 하자. 예를 들어 우리 나라 사람들에게는 매우 직관적일 수 있는 한글 프로그래밍 언어인 '씨앗'은 외국인들이 보기에 거의 암호와도 같은 것이다. 차라리 사칙연산밖에 못하는 사람이 미적분을 공부하는 것이 더 쉬울 것이다.관점에 따라 쉬울 수도 어려울 수도 있다서론이 길었는데, 그렇다면 과연 자바는 쉬운 언어인가 어려운 언어인가? 자바는 C++가 갖고 있는 많은 개념을 포기했으므로 C++에 비해 상대적으로 쉬운 언어라고 할 수 있고, 자바의 문법은 언어가 내재하고 있는 개념을 상대적으로 간결하게 나타낼 수 있게 해준다는 점에서 또한 쉬운 언어라고 할 수 있다. 대부분의 상황에서 같은 개념을 나타내는 자바 코드는 C++ 코드와 비슷하거나 C++ 코드보다 간결하다.그렇다면 C++ 언어 설계자가 자바 언어 설계자보다 학식이 부족해서 그렇게 됐거나, C++을 건성으로 설계했거나, 인터넷에 십 년이 넘도록 떠돌고 있는 루머 'C++는 장난으로 만든 언어이다'가 사실일까? 그렇지 않다. 만약에 우리가 언어를 쉽고 간결하게 만들기 위해 자바에서 제거된 개념들을 사용해야 한다면 당연히 같은 개념을 프로그래머가 수동으로 구현해야 하는 자바 코드보다는 언어가 제공하는 이점을 살려 작성된 C++ 코드가 훨씬 더 간결해질 것이다. 그 당연한 결과에 이르는 과정을 조금 풀어서 설명하면, 언어가 프로그래머가 나타내고자 하는 의도(Intention)에 대한 개념(Abstraction)을 지원하지 못하면 프로그래머는 주석, 변수나 함수 이름 등의 적절한 활용을 통해 해당 개념을 직접 구현해 자신의 의도를 수동으로 나타내줘야 하기 때문이다.C++는 자바에 비해 상대적으로 오래된 언어이고, 많은 패러다임의 변화를 겪으면서 계속 진화해온 언어이다. 기술이란 마치 살아있는 생명과도 같아서 주변의 환경에 적응하고 진화하는 과정에서 기존의 기능을 새로운 환경에 맞게 이차적응(마치 거미가 진화하는 과정에서 거미줄을 초기에는 집을 꾸미기 위한 용도로 쓰다가, 먹이를 감지하기 위한 용도로 발전시키고, 이를 또 다시 먹이를 포획하기 위한 용도로 발전시켰듯이)을 시키는가 하면, 어떤 기능은 흔적 기관처럼 쓸모 없어지기도 한다. C++에 뭔가 깔끔해 보이지 않는 부분이 있다면 오랜 시간 성숙해온 언어에 남아있는 진화의 흔적이거나 우리의 지식이 부족해서 그 용도를 미쳐 알지 못하기 때문일 것이다.플랫폼 독립성이 필요한 이유자바의 플랫폼 독립성에 대해 이야기하기 전에 플랫폼 독립성이라는 것이 왜 필요한지에 대해 생각해보자. 사실 플랫폼 독립성이라는 특성은 그 자체로 하나의 목적이라기 보다 '이식성(portability)'이라는 더 큰 목적을 이루기 위한 한 가지 방편으로서 존재한다. 그리고 이식성은 '생산성(productivity)'이라는 더 큰 목적을 이루기 위해 존재한다. 즉, C/C++에서 말하는 이식성과 자바나 닷넷이 주장하는 플랫폼 독립성은 생산성의 향상이라는 같은 목적을 가지며, 요지는 플랫폼 독립성이나 이식성이라는 이름이 아니라 그러한 기술들로 인해 얼마만큼 실제적인 생산성의 향상이 이뤄졌는가 하는 부분이다. 많은 개발자의 목적은 생산성 향상에 있다. 그래야 일을 한 시간이라도 적게 하고, 뭔가 더 많은 일을 한 것처럼 상사에게 보고 할 수 있으니까. 바로 필자처럼 게으른 개발자들의 궁극적인 목적이며 애타는 바람이다.지난 특집에 따르면 자바의 클래스 파일은 JVM이 있어야만 실행되므로 자바의 플랫폼 독립성은 허구이며, 실제적으로 C/C++로 이식성 있는 코드를 작성해 소스코드 형태로 배포하는 것이 더 현실적인 대안일 수 있다고 했다. 이 주장에 대해 몇 가지 이야기를 하고 싶다. 첫째, JVM이 모든 플랫폼에 이식되어 있는 것이 아니라서 문제라면, C/C++로는 모든 플랫폼에 이식할 수 있는 코드를 작성할 수 있을 것인가? 둘째, C/C++가 제공하는 이식성은 자바가 제공하는 플랫폼 독립성에 비해 얼마만큼 실제적인 생산성 향상을 가져오는가? C/C++가 제공하는 이식성과 자바의 플랫폼 독립성에 대해 간단하게 살펴보는 것으로 이 두 가지 의문에 대한 답을 대신하도록 하자.ANSI/ISO C 표준은 특정 C 코드가 여러 플랫폼에서 어떻게 동작해야 하는지를 기술하고 있다(C++는 ANSI/ISO C 표준에 기반한다). ANSI/ISO C 표준에서는 '구현에 따라 다르게 정의된 동작(implementation-defined behavior)', '지역에 따라 다르게 정의된 동작(locale-specific behavior)', '단일하게 명시되지 않은 동작(unspecified behavior)', '정의되지 않은 동작(undefined behavior)"이라는 말로 정의하고 있는데 각각의 뜻을 풀어쓰면 다음과 같다.◆ 구현에 따라 다르게 정의된 동작(implementation-defined behavior) : 컴파일러에 따라 코드가 어떻게 실행될 지 결정되며, ANSI/ISO C 표준에서는 그 동작을 정의하지 않지만 컴파일러(Implementation) 제공자에 의해 명확한 행위가 명시되어 있다.◆ 지역에 따라 다르게 정의된 동작(locale-specific behavior) : 국가나 문화, 언어나 관습 등 지역에 따라 어떻게 실행될 지가 결정되며, ANSI/ISO C 표준에서는 그 동작을 정의하지 않지만 컴파일러(Implementation) 제공자에 의해 명확한 행위가 명시되어 있다.◆ 단일하게 명시되지 않은 동작(unspecified behavior) : 코드가 동작할 수 있는 몇 가지 가능성을 표준이 정의하고 있으나 명확히 어떤 하나의 동작이 수행된다는 것은 보장하지 않는다.◆ 정의되지 않은 동작(undefined behavior) : 코드가 어떻게 동작할지 전혀 정의되어 있지 않다. 이러한 코드를 실행한 결과로 모니터가 폭발하거나, 모니터에 있던 오피스 강아지(한국 MS에서 번역한 이름으로는 '재롱이')가 화면 밖으로 튀어나올 수도 있다. 그리고 ISO/ANSI C 표준에 따르면 이 상황은 정상이다."이러한 부분이 얼마나 된다고..."라고 생각할지 모르지만 생각보다 심각하다. 예를 들어 부호있는 정수(integer)에 대한 우측 시프트 연산의 결과로 부호 비트가 전파되는지의 여부는 구현에 따라 다르게 정의된 동작(implementation-defined behavior)이라서 16비트 부호 있는 정수 -2(1111 1111 1111 1110)를 우측으로 1회 시프트한 결과가 -1이 될지, 32767(0111 1111 1111 1111)이 될지는 구현에 따라 달라진다. islower() 함수는 지역에 따라 다르게 정의된 동작(locale-specific behavior)이므로 특정 지역에서는 알파벳 소문자 26자 이외의 문자에 대해서도 true를 되돌릴 수도 있다. 함수의 인자 중 어느 것이 먼저 평가되는지 하는 부분도 단일하게 명시되지 않은 동작(unspecified behavior)이라 앞쪽의 인자가 먼저 평가될지 뒤쪽의 인자가 먼저 평가될지 알 수 없다. 이처럼 당연히 잘 돌아갈 것으로 생각한 C/C++ 코드가 특정 환경에서는 오류를 발생시킬 수도 있다.이러한 상황을 모두 숙지하고 모든 플랫폼에 이식할 수 있는 C/C++ 코드를 작성한다는 것은 현실적으로 거의 불가능하다. 그리고 앞으로 새로 개발될 알 수 없는 플랫폼까지 고려한다면 사태는 더욱 심각하다. 물론 눈을 현실로 돌리면 안도의 한숨을 내쉴 수 있다. 실제적으로 개발한 프로그램을 현재 존재하는 모든 플랫폼과 앞으로 개발된 모든 플랫폼에 배포해야 할 그런 상황은 없기 때문이다.자바의 플랫폼 독립성은 허구인가이번에는 자바가 제공하는 플랫폼 독립성에 대해 살펴볼 차례이다. 과연 자바의 플랫폼 독립성은 허구인가? 'Write Once, Run Everywhere'는 단지 광고 문구일 뿐이고, 현실은 "Write Once, Test and Debug Everywhere'일까? 그러한 오해를 풀기 위해 'Write Once, Run Everywhere'의 좀 더 정확한 의미를 살펴보자. 다음은 자바 언어 명세서(Java Language Specification)의 일부를 인용한 것이다.자바 프로그래밍 언어는 되도록이면 구현에 대한 종속성이 최소화되도록 특별히 설계된 범용적이고 동시성을 제공하는 클래스 기반의 객체지향 언어이다. 이러한 특성은 개발자들이 단 한번 프로그램을 작성하면 인터넷의 어떤 곳에서도 그 프로그램이 실행될 수 있도록 한다. …중략… 시간에 대한 의존성이나 다른 비결정론적인 사항들을 제외한다면 주어진 적절한 시간 내에 적절한 메모리 공간상에서 실행되는 자바 프로그램은 모든 경우에 모든 기계에서 동일한 결과를 수행하여야 한다(The Java programming language is a general-purpose concurrent class-based object-oriented programming language, specifically designed to have as few implementation dependencies as possible. It allows application developers to write a program once and then be able to run it everywhere on the Internet. This book attempts a complete specification of the syntax and semantics of the language. We intend that the behavior of every language construct is specified here, so that all implementations will accept the same programs. Except for timing dependencies or other non-determinisms and given sufficient time and sufficient memory space, a program written in the Java programming language should compute the same result on all machines and in all implementations).이 정도면 'Write Once, Run Everywhere'에 대한 비교적 정확한 설명이라고 할 수 있다. 여기에서 중요한 것은 '비결정론적인 사항(non-determinisms)을 제외한다면'이라는 부분인데 바로 이 부분을 생각하지 않으면 자바의 플랫폼 독립성이 허구인가 하는 의구심을 품게 된다. 비결정론적인 사항이란 언어의 명세서 상에서 정확히 명시하고 있지 않는 부분(혹은 할 수 없는 부분) 또는 실행 시간(Run-time)의 상황(Context)에 따라 어떻게 작동할 지가 결정되는 사항 등을 말하는데, 자바뿐 아니라 C/C++를 비롯한 세상의 거의 모든 범용 고급 언어(GP-HLL : General Purpose High Level Language)들은 이러한 문제를 모두 갖고 있다. 그러한 의미에서 '진정한 플랫폼 독립성'이라는 환상은 존재하지 않는다. 그러므로 우리는 플랫폼 독립성이라는 말을 '얼마나 더 생산성 향상에 도움을 주는 바이너리 호환성(C/C++의 소스 호환성에 대비되는)을 제공하는가'라는 뜻으로 생각하는 것이 옳다.자바가 제공하는 바이너리 호환성은 확실히 C/C++의 소스 호환성에 비해 '비결정론적인 사항(non-determinisms)'을 적게 갖고 있으며, 플랫폼 독립적인 코드를 만들기 위해 개발자가 해야 할 노력을 크게 줄여준다(그렇다고 해서 아무 생각 없이 컴파일만 잘 되면 문제없다는 식으로 프로그래밍을 하면, 자바뿐만 아니라 가까운 미래에 플랫폼 독립성을 제공한다고 주장하는 어떠한 언어가 나오더라도 결국 플랫폼 독립성은 달성할 수 없게 된다).이제 앞서 제기한 두 가지 물음(C/C++로는 모든 플랫폼에 이식할 수 있는 코드를 작성할 수 있을 것인가? C/C++이 제공하는 이식성은 얼마만큼 실제적인 생산성 향상을 가져오는가?)에 대한 답을 해보자. C/C++로는 모든 플랫폼에 이식할 수 있는 코드를 작성한다는 것은 생각한 것보다 어려운 작업이다. 배포할 대상 플랫폼을 한정하고, 플랫폼 별 특성을 잘 파악한 후 조심스럽게 코딩한다고 해도, 이는 단일 플랫폼만을 고려했을 때에 비해 엄청난 생산성의 저하를 야기한다(물론 플랫폼별로 따로 작업을 하는 것에 비하면 조금 낳은 상황일 수 있다).많이 쓰이는 플랫폼에는 이미 JVM이 존재한다는 점에서 단지 생산성만을 두고 본다면, 일반적으로 자바가 제공하는 플랫폼 독립성이 C/C++가 제공하는 이식성에 비해 월등히 많은 장점을 제공한다. 그럼 도대체 C/C++는 필요가 없는 언어라는 소리인가? 물론 그렇게 주장할 수는 없다. 지금까지 한 이야기는 일반적인 상황에 대한 이야기일 뿐이다. JVM이 이식되지 않은 플랫폼이나, JVM의 안정성이 검증되지 않은 플랫폼을 대상으로 하는 경우 자바를 아예 선택할 수 없게 된다. 또는 생산성 이외의 요인(예를 들어 성능 같은)이 더 중요하게 작용하는 경우 역시 자바는 썩 좋은 대안이 아니다.긴 글을 통해 필자가 하고 싶었던 말은 자바가 '완벽한 플랫폼 독립성'이라는 이상을 실현하지 못했다면, 마찬가지로 C/C++ 역시 '완벽한 이식성'이라는 이상으로부터는 여전히 부족한 언어라는 것이다.자바는 폐쇄적인 기술인가지난 특집에서는 구현언어로 자바를 선택할 것을 결심했다면 기존의 익숙한 라이브러리들을 버리고 자바 표준 API를 새로 배워야 하는데, 이것이 자바의 폐쇄성을 보여주는 일례라고 지적했다. 물론 GPL이나 LGPL 하의 오픈소스를 주장하는 GNU 해커(크래커와 구별되는 좋은 의미에서의 해커)의 관점에서 자바소프트의 라이선스 정책은 폐쇄적일 수 있으나 자바라는 언어 자체가 기술적으로 폐쇄적인 것은 아니다.이것에 대해 논의하기 전에 다른 질문을 던져 보자. 왜 기존의 익숙한 프로그래밍 언어를 쓰지 않고 자바를 사용하려고 결심했는가? 자바가 제공하는 플랫폼 독립성을 제공받아야 할 필요가 있거나 자바가 제공하는 특정 API를 이용하기 위해서, 또는 객체지향 프로그래밍을 하기 위해서, 대부분 이 셋 중의 한 가지 답이 나올 것이다(이외에 '그냥 자바가 좋아서'라는 답도 가능한데, 정말 그렇다면 세상 누구도 그 결정을 말릴 수 없을 것이다).자바가 제공하는 플랫폼 독립성을 제공받아야 할 필요가 있어 기존의 익숙한 프로그래밍 언어와 라이브러리를 버리고 자바를 선택한다고 대답했다면, 기존에 사용했던 언어나 라이브러리가 플랫폼에 종속적이거나 원하는 수준의 플랫폼 독립성을 제공하지 못한다고 판단했기 때문이다. 기존의 언어와 라이브러리가 원하는 수준의 플랫폼 독립성을 제공한다면 아예 자바를 쓰지 않거나 JNI를 통해 기존 라이브러리를 사용하면 되므로 자바의 폐쇄성과는 무관할 것이다. 이 부분은 이식성이나 플랫폼 독립성에 대한 논의와 어느 정도 겹치는 부분이기도 하다. 자바만큼 현실적인 플랫폼 독립성을 제공하는 기술이 있다면 당연히 자바와 혼용할 수 있을 것이다. 자바를 사용할 때에 자바 API만을 사용하는 이유는 이식성 있는 C/C++ 코드를 작성할 때 이식성 있는 라이브러리만을 사용하는 것과 같다.자바가 제공하는 특정 API를 이용하기 위해 자바를 선택한다면 기존의 언어와 라이브러리는 자바의 특정 API가 제공하는 기능을 지원하지 못하거나 지원하더라도 배우기가 무척 어려워 차라리 잘 모르는 자바로 만드는 게 더 낳을 정도의 상황이라고 판단했기 때문이다. 이 역시 자바의 폐쇄성과는 무관하다.마지막으로, 객체지향 프로그래밍을 하기 위해서 자바를 선택했다고 한다면 기존의 프로그래밍 언어보다 자바가 조금 더 객체지향적인 언어라고 판단했기 때문이다. 이 경우에도 비객체지향적이지만 익숙한 기존의 라이브러리를 같이 쓰고자 한다면 JNI라는 길이 열려있다.자바는 '돈' 지향 언어?비슷한 주제라고 생각되는 '돈 지향 언어(Money Oriented Language)'에 대해서도 생각해 보자. 이 이야기를 하기 전에 음악 이야기를 먼저 해 보는 것이 좋을 것 같다. 요즘 국내 가요를 두고 '음악이 너무 상업적이다'라는 얘기를 하는 사람들을 많이 보게 된다. 이런 말을 하는 사람들(필자를 포함해서)이 단지 음악이 상업적이라는 것 자체를 비난하는 것은 아니다. 사실 음악이 상업적이라는 것 자체가 잘못된 것은 아닐 것이다. 음악을 하는 사람들도 돈은 벌어야 할 것 아닌가? 문제는 상업성이 있고 없음에 있는 것이 아니라, 음악성(예술성)의 부재에 있다. 음악이면 음악답게 음악성을 지향해야 할 것이고, 상업성은 그 후에 생각하는 것이 옳다. '음악이 너무 상업적'이라는 말은 사실 '음악성은 부족하고 너무 상업성만을 추구한다'라는 뜻으로 인식돼야 한다. 그러나 사실은 음악성과 상업성이 서로 배타적이지 않다는 것은 굳이 말로 설명하기 보다 핑크 플로이드나 비틀즈, 도어즈, 들국화 등 훌륭한 그룹의 작품을 소개하는 것으로 대신할 수 있을 것이다. 음악성이 있다고 해서 상업성이 없거나, 상업성이 있다고 해서 음악성이 없는 것은 아니라는 뜻이다.GNU를 지지하는 일부 사람들의 생각하는 것과 달리 기술(프로그래밍 언어를 포함한) 또한 이와 별반 다르지 않다. 어떠한 기술이 상업적이라고 해서 기술적인 가치가 떨어진다거나, 너무 기술적인 부분만을 강조하기 때문에 상업적인 가치가 떨어지는 것은 아니다. 물론 음악성이라고는 조금도 찾아볼 수 없이 철저히 상업성으로만 무장한 몇몇 사람들이 스스로를 가수라고 칭하며 노래를 하고 있듯이 컴퓨터 분야에도 그런 현상이 있기는 하다.비슷한 주제 내에서 이런 특성을 갖고 있는 제품을 들자면, 비주얼 J++와 마이크로소프트 JVM, 그리고 IE를 들 수 있겠다. 무엇이 기술을 더 좋은 방향으로 발전시킬 수 있는지 충분히 알고 있으면서도 단지 돈을 벌 수 있는 방향과 다르기 때문에 따르지 않는다면, 이런 것을 두고 바로 '돈 지향'이라고 말할 수 있을 것이다. 앞에서 열거한 세 가지 기술은 AWT에 대한 RAD를 지원하는 조금 더 좋은 자바 IDE, RMI를 지원하는 조금 더 좋은 자바 VM, 자바 2를 지원하는 조금 더 좋은 자바 호환 브라우저가 될 수 있었지만, 돈 때문에 절름발이 기술이 되어버린 사례라고 할 수 있다. 물론 그렇다고 해서 VJ++, MS JVM, IE가 기술적으로 아무런 가치도 없는 것들이라는 뜻은 아니다. 비주얼 J++와 M SJVM은 비주얼 스튜디오 닷넷과 닷넷 프레임워크의 전신이라고 할 수 있으며, IE는 절름발이 자바 브라우저이지만 한편으로는 필자가 아는 한 가장 좋은 HTTP 클라이언트이다.하물며 자바나 C#은 어떤가? 단순히 같은 기술을 재탕한 것에 불과한 쓸모 없는 기술인가? 그럼 이 도무지 쓸모 없는 기술을 선택하는 기업이나, 이 별 볼일 없는 언어를 예제로 사용하는 수많은 소프트웨어 공학 관련 저서의 저자는 무슨 생각을 하고 있었던 걸까? 퀘이크 시리즈나 둠 등으로 유명한 천재 프로그래머 존 카맥은 자바에 대해 '장기적인 안목으로 봤을 때, C나 C++보다 훌륭한 언어'라고 언급한 바 있다(그는 많은 사람들이 C는 어셈블리보다 느려서 게임을 만들기에 적합하지 않다고 생각하고 있을 때부터 C를 이용해 획기적인 게임을 만들어왔다).방대한 자바 API를 어떻게 배워야 하나1996년에 자바가 처음 발표된 이후로 지금까지 수많은 라이브러리들이 자바 표준 API로 포함돼 왔다. 그 결과 현재의 자바 표준 API는 그야말로 공룡같이 불어나 버렸다. 하지만 너무나 당연하게도 자바의 모든 API를 다 공부해야만 자바로 프로그래밍을 할 수 있는 것은 아니다. 자신이 원하는 기능이 어느 패키지에 있는지 찾을 방법만 알고 있으면(즉 Javadoc 문서를 읽을 줄 안다면) 필요할 때 찾아서 Tm면 되는 것이다. 더군다나 기존에 이미 익숙하게 쓰던 라이브러리가 있으면서 자바가 제공하는 플랫폼 독립성이 필요하지 않은 경우에는(또는 그 라이브러리가 어떠한 형태로든 이식성을 보장한다면) 그냥 그 라이브러리를 사용하면 된다. 자신의 자바 프로그램이 순수 자바인지 아닌지는 중요하지 않다. 중요한 것은 원하는 바를 이루는 것이지 그걸 '순수 자바'로 이루었는가 하는 문제가 아니다. 이 부분은 지난 12월호 특집에도 잘 나와 있으므로 언급하지 않겠다.혹시 있을지도 모를 오해를 풀기 위해 또 이야기하자면 계속 덩치가 불어나는 방대한 양의 자바 API는 문제라기 보다 좋은 방향으로의 발전이라고 볼 수 있다. 자바 API를 공부하는 것이 새로운 '특수 기능 언어'를 배우는 것과 마찬가지라는 말은 일리가 있다. 하지만 그건 자바 API뿐 아니라 이 세상의 모든 라이브러리가 그렇다. 특히 라이브러리가 이식성을 고려하지 않고 설계돼 있다면 각 플랫폼별로 같은 기능을 하는 서로 다른 라이브러리를 찾아서 익혀야 하는데 이 또한 큰 문제이다. 이식성을 고려하지 않은 라이브러리는 대부분 시스템의 하부구조에 대한 충분한 수준의 추상성을 제공하지 않고 있는데, 이런 경우 결국 프로그래머는 각 시스템이 해당 기능(예를 들면 네트워킹)을 어떻게 지원하는지를 모두 공부해야 한다. 그런 점에서 그나마 모든 자바 표준 API는 시스템에 대한 단일한 View를 제공하고 있으며, 서로 다른 API들도 자바 언어의 다양한 관습(Naming Convention 등)을 따르고 있기 때문에 학습곡선이 크게 줄어든다는 추가적인 장점도 가진다.속도냐, 생산성이냐대부분의 상황에서 자바는 C나 C++로 만들어진 프로그램에 비해 느리게 실행된다. 특히 자바 GUI 형태의 애플리케이션(그 중에서도 스윙)은 유명하다. 하지만 이러한 종류의 지적은 전혀 무의미하다. 굳이 이런 저런 이야기를 꺼낼 필요도 없다. 과거에 사람들이 C나 C++로 상용 프로그램을 제작하기 시작하자 어셈블리 프로그래머들이 C나 C++의 속도 문제를 지적했는데, 그 때에 C, C++ 프로그래머들이 했던 답변을 그대로 돌려주고 싶다.스윙으로 UI를 만들었을 때 속도가 느려지는 문제는 굳이 비유하자면 옛날 옛적 도스 시절에 BGI(Borland Graphics Interface)로 화면 로직을 작성한 프로그램이 그래픽 메모리와 그래픽 카드를 직접 제어하도록 작성된 프로그램에 비해 상대적으로 느렸던 것과 비슷하다. 그런 식으로 성능을 희생한 결과, 우리가 얻은 것은 무엇인가? 바로 생산성의 향상이다. 사람들이 자바나 C#을 선택하는 이유는 속도가 느리다는 사실을 모르기 때문이 아니라, 생산성이 향상된다는 사실을 알기 때문이다.그리고 또 한 가지 중요한 점은 VM 기술의 눈부신 발전이다. JVM이나 CLR이 사용하는 동적 컴파일러(JIT Compiler 등) 기술은 몇몇 상황에서 C나 C++가 생성한 정적 컴파일러에 비해 더 빠른 성능을 낸다. 그 이유는 정적 컴파일러의 태생적인 한계에서 비롯된다. 정적 컴파일러가 적용할 수 있는 최적화 기술의 근거는 모두 컴파일 시간(Compile-time)에 결정되는 반면, 동적 컴파일러가 적용할 수 있는 최적화 기술의 근거는 실행 시간(Runtime)에 결정되기 때문이다. 이론적으로 동적 컴파일러는 정적 컴파일러가 적용할 수 있는 모든 최적화 기술을 적용할 수 있으며, 거기에 더해서 실행 시간에 수집된 추가적인 정보로 지속적인 최적화를 수행할 수 있다. 말로만 할게 아니라 자바 애플릿으로 구현된 퀘이크를 한번 구경해 보기 바란다(http://wwwstage.valpo.edu/home/student/jmiller/jquake/JQuakeWeapons.htm).하드웨어가 제공하는 3D 가속 기능도 전혀 없이 순수하게 자바 코드로만 구현되어 있으면서도 우리가 상상했던 것 이상의 성능을 보여주고 있다. 평소 여기 저기에서 '자바도 리니지 정도의 게임을 만들 수 있을 만큼 충분한 성능을 낼 수 있다'고 주장하고 다녔던 필자조차도 상상하지 못했던 성능이었다.프로그래밍 언어는 도구일 뿐필자 역시 기술이 너무 상업적인 방향으로 흘러가는 것을 경계하는 시각에 대해 어느 정도 공감하고 있다. 그러나 특정 회사와 관련해 과거에 자신이 겪어온 좋지 못한 경험을 그 회사의 새로운 기술을 평가하는 절대적인 잣대로 사용해서는 안 될 것이다. 기술을 선도하고 있는 업체들이 보여주는 비교적 최근의 모습은 환영할 만한 것으로 보인다. JCP를 기반으로 하는 과거에 비해 개방된 자바소프트의 자바 표준화 정책이나, 과거와 달리 다양한 표준을 적극 수용한 닷넷 기술을 통한 MS의 정당한 경쟁 등에 대해 매우 긍정적으로 평가한다.짧지 않은 이 글을 통해 필자가 내리고 싶은 결론은 결국 지난 특집의 결론과 다르지 않다. 어쨌든 프로그래머에게 있어 프로그래밍 언어는 도구일 뿐이다. 프로그래밍 언어는 활용의 대상일 뿐이지, 광신이나 추종의 대상은 아니다. 특정 기술에 대한 광신에 가까운 선호 역시 문제이긴 하지만, 기술에 대한 필요 이상의 평가절하도 문제일 것이다. 프로그래머에게 있어 중요한 것은 도구에 대한 객관적인 평가와 적절한 활용이다.@