번역 일지 * 04-01-26 번역 완료 * 04-01-08 번역 시작 ---- '''Being Popular''' 인기 있다는 것 http://www.paulgraham.com/popular.html Copyright © 2001 Paul Graham ''(이 논설은 새로운 언어를 위한 일종의 사업 계획으로 작성되었다. 그래서 좋은 프로그래밍 언어가 갖춰야 할 가장 중요한 특징인 '매우 강력한 추상화'에 대한 언급이 (당연한 것이라고 생각했기 때문에) 빠져 있다.)'' 친구 하나가 언젠가 어떤 저명한 운영 체제 전문가에게 정말로 좋은 프로그래밍 언어를 고안하고 싶다고 말했다. 그 전문가는 그 친구에게 그것은 시간 낭비일 것이라고 했다. 또 프로그래밍 언어가 인기가 있거나 없게 되는 것이 그 언어의 장점에 근거한 것이 아니므로, 그 언어가 아무리 좋아도 아무도 그것을 사용하지 않을 것이라고 했다. 최소한 이 말은 그 친구가 고안한 그 언어에 그대로 들어맞았다. 무엇이 어떤 언어를 인기 있게 하는가? 인기 있는 언어들은 그 인기를 누릴 만한가? 좋은 프로그래밍 언어를 정의해 보는 것이 가치가 있는가? 그렇다면 어떻게 할 것인가? 나는 이 의문들에 대한 해답을 해커들을 관찰하고 그들이 원하는 것이 무엇인지 앎으로써 찾을 수 있을 것이라고 생각한다. 프로그래밍 언어는 해커를 위해 존재하는 것이며, 프로그래밍 언어는 해커들이 그것을 좋아할 때에만 (이를테면, 표시적 의미론(denotational semantics)이나 컴파일러 설계의 연습으로서가 아니라) 프로그래밍 언어로서 좋은 것이다. [[TableOfContents]] == 인기의 역학 == 대부분의 사람들이 프로그래밍 언어를 단순히 그 장점 때문에 선택하지 않는다는 것은 분명한 사실이다. 대부분의 프로그래머들은 다른 사람에게서 어떤 언어를 사용하라는 지시를 받는다. 하지만 프로그래밍 언어의 인기에 그런 외부 요인들이 미치는 영향은, 클 것 같은 생각이 들 때도 있지만, 실제로는 그렇게 크지 않은 것 같다. 더 큰 문제는 좋은 프로그래밍 언어에 대한 해커들의 생각이 많은 언어 설계자들의 생각과 일치하지 않는 것이라고 생각한다. 그 둘 중에서 해커들의 의견이 더 중요하다. 프로그래밍 언어는 수학의 정리(theorem)가 아니다. 그것은 도구이며, 사람들을 위해 고안되었으며, 따라서 신발이 인간의 발에 맞게 고안되어야 하듯이, 프로그래밍 언어는 인간의 강점과 약점에 맞게 고안되어야 한다. 신발을 신었을 때 꽉 낀다면, 조각 작품으로서 아무리 우아하다 해도, 그것은 나쁜 신발이다. 대다수의 프로그래머들이 좋은 언어와 나쁜 언어를 구분하지 못할 수 있다. 하지만 이것은 다른 어떤 도구들에 대해서도 다를 바 없다. 이 말은 좋은 언어를 고안해 보려는 것이 시간 낭비라는 뜻이 아니다. 특급 해커(expert hacker)들은 척 보기만 해도 좋은 언어를 가려낼 수 있으며, 또 그것을 사용할 것이다. 특급 해커들은 분명히 극소수이지만, 그 극소수가 모든 좋은 소프트웨어들을 작성하고 있으며, 그들의 영향력은 다른 모든 프로그래머들이 그들이 쓰는 언어를 그대로 따라 쓰게 될 정도이다. 실제로 그것은 단순한 영향력이 아니라 지배력이라고 할 만하다. 전문 해커들이 바로, 상사나 지도교수처럼, 다른 프로그래머들에게 어떤 언어를 사용하라고 지시하는 그 사람이다. 전문 해커들의 의견이 프로그래밍 언어의 상대적 인기를 결정하는 유일한 힘은 아니다. -- 코볼(Cobol) 같은 구닥다리(legacy) 소프트웨어와 에이다(Ada)나 자바(Java) 같은 떠버리(hype)도 일익을 담당하고 있으니 말이다. -- 하지만 긴 기간이 지나면 그들의 의견이 가장 강력한 힘이 될 것이다. 초기의 비판적 집단(critical mass)과 충분한 시간이 주어지면, 어떤 프로그래밍 언어든 대략 그 가치에 맞는 인기를 얻게 될 것이다. 그리고 인기는 좋은 언어와 나쁜 언어를 더욱 갈라놓는다. 실제 사용자들의 의견은 항상 기능 개선으로 이어지기 때문이다. 인기 있는 언어들이 그 동안 얼마나 변화해 왔는지 살펴보라. 펄(Perl)과 포트란(Fortran)은 극단적인 사례들이겠지만, 리스프(Lisp)조차도 많이 변화해 왔다. 리스프 1.5는, 예를 들어, 매크로 기능이 없었는데, MIT의 해커들이 실제 프로그램을 작성하기 위해 두 해 동안 리스프를 이용하면서 나중에 그 기능이 고안되었다. ''주: 최신의 아이디어에 매우 근접한 이 매크로 기능은, 리스프 1.5가 배포되고 2년이 지난 1964년에 티머시 하트(Timothy Hart)가 제안했다. 변수 포획(variable capture)과 중복 계산(multiple evaluation)을 피할 방법이 처음에는 빠져 있어서, 하트의 예제들은 양쪽 모두에 말려들기 쉽다.'' 그래서 인기 있는 언어가 되기 위해 좋은 언어가 되어야 하든 말든 상관없이, 나는 좋은 언어가 되기 위해서는 인기가 있어야 한다고 생각한다. 그리고 인기를 유지하기 위해서는 꾸준히 좋아야 한다. 프로그래밍 언어의 기술 수준은 가만히 머물러 있지 않는다. 그런데 우리가 지금 사용하는 리스프는 MIT에서 1980년대 중반 사용하던 것과 거의 똑같다. 그 때가 리스프의 사용자 층이 충분히 넓고 요구도 많았던 마지막 시기였기 때문이다. 물론, 해커들은 언어를 사용할 수 있게 되기 전에 그것에 대해 알아야 한다. 그들은 어떻게 소식을 접할까? 다른 해커들을 통해서이다. 그런데 다른 해커들이 그 언어에 대해 들어보기라도 하기 위해서는 그것을 처음으로 사용하는 해커 그룹이 있어야 한다. 나는 이 그룹이 얼마나 크면 되는지 궁금하다. 얼마나 많은 사용자가 모이면 비판적 집단(critical mass)이 되는가? 언뜻 드는 생각으로는, 20명이면 될 것 같다. 어떤 언어의 독립(separate) 사용자, 다시 말해서 스스로 그 언어를 사용하기로 결심한 사용자가 20명이라면, 나는 그것이 현실 세계에 들어왔다고 간주할 것이다. 거기까지 이르는 것은 쉽게 되지 않는다. 사용자가 0명에서 20명이 되는 것이, 20명에서 1,000명이 되는 것보다 어렵다고 해도 나는 놀라지 않을 것이다. 처음 20명의 사용자를 확보하는 가장 좋은 방법은 트로이 목마를 이용하는 것이다. 즉, 사람들이 원하는 응용 프로그램을 제공하면서 그것을 그 새로운 언어로 작성하는 것이다. == 외부 요인들 == 프로그래밍 언어의 인기에 영향을 미치는 외부 요인 하나를 인정하면서 시작해 보자. 인기를 얻기 위해 프로그래밍 언어는 인기 있는 시스템의 스크립트 언어(scripting language)가 되어야 한다. ''역자 주: 이 글에서 스크립트 언어는 넓은 의미로 쓰인다. (인터프리터 언어인가 아닌가에 상관없이) 시스템 운영을 위해 주로 쓰이는 언어라고 보면 되겠다.'' 포트란과 코볼은 초창기 IBM 메인프레임의 스크립트 언어였다. C는 유닉스의 스크립트 언어였고, 나중에는 펄이 그렇게 되었다. Tcl은 Tk의 스크립트 언어이다. 자바와 자바스크립트는 웹 브라우저의 스크립트 언어로 만들어졌다. 리스프는 크게 인기 있는 언어가 아니다. 그것이 크게 인기 있는 시스템의 스크립트 언어가 아니기 때문이다. 지금 인기가 남아 있다면 그 역사는 그것이 MIT의 스크립트 언어였던 1960년대와 1970년대로 거슬러 올라간다. 그 당시 많은 훌륭한 프로그래머들은 어떻게든 MIT와 연관되어 있었다. C가 나오기 전인 1970년대 초에는 맥리스프(MacLisp)라고 불리던 리스프의 MIT 판(dialect)이 진지한 해커들이 쓰고 싶어 했던 거의 유일한 프로그래밍 언어였다. 오늘날 리스프는 두 가지의 적당히 인기 있는 시스템, 즉 이맥스(Emacs)와 오토캐드(Autocad)의 스크립트 언어이며, 그래서 나는 오늘날 대부분의 리스프 프로그래밍이 이맥스 리스프(Emacs Lisp)나 오토리스프(AutoLisp)로 이뤄지는 것이 아닌가 하고 생각한다. 프로그래밍 언어는 고립하여 존재하지 않는다. '해킹하다'는 타동사이다. -- 해커는 보통 무엇인가를 해킹한다. -- 실제로 언어들은 무엇을 해킹하는 데 쓰이는가에 따라 판가름 난다. 그래서 인기 있는 언어를 고안하고 싶다면, 언어 외에 다른 것들도 공급하거나, 그 언어가 기존 시스템의 스크립트 언어를 대체하도록 고안해야 한다. 커먼 리스프(Common Lisp)가 인기가 없는 이유 중 하나는 그것이 외톨이이기 때문이다. 그것도 처음에는 해킹할 시스템과 함께 등장했다. 리스프 머신(Lisp Machine)이 그것이다. 그런데 1980년대가 되면서 리스프 머신들이 (병렬 컴퓨터들도 함께) 다목적 프로세서들의 계속 향상되는 성능에 압도되었다. 커먼 리스프가 유닉스에 어울리는 스크립트 언어였다면 여전히 인기가 있었을 것이다. 슬프지만, 그것은 유닉스와 지독하게도 안 어울린다. 이런 상황을 설명하는 한 가지 방법은 언어가 그 장점으로 판가름 나지 않는다고 말하는 것이다. 또 다른 관점은, 프로그래밍 언어가 어떤 것의 스크립트 언어가 되지 않는다면 그것은 프로그래밍 언어가 아니라는 것이다. 이 말이 놀랍게 들린다면 그것이 불공평하게 느껴지기만 할 것이다. 이것은 프로그래밍 언어에 대해, 이를테면 그것으로 구현된 제품(implementation)을 기대하는 것만큼 전혀 불공평한 일이 아니라고 생각한다. 이것은 프로그래밍 언어가 갖춰야 할 한 부분일 뿐이다. 프로그래밍 언어는 그것으로 잘 구현된 제품(implementation)이 있어야 하고, 물론 그것은 무료여야 한다. 회사는 소프트웨어에 돈을 지불하겠지만, 해커들은 그러지 않을 것이다. 바로 그 해커들의 마음을 끌어야 한다. 언어는 그에 대한 책도 있어야 한다. 책은 얇고, 문장이 좋고, 좋은 예제가 많아야 한다. K&R이 여기에 딱 맞는다. ''역자 주: 브라이언 커니건(Brian Kernighan)과 데니스 리치(Dennis Ritchie)의 책 "The C Programming Language". 특히 1978년에 나온 초판.'' 지금으로서 나는 그 언어에 대해 오라일리(O'Reilly)에서 출판된 책은 있어야 한다고 말하고 싶다. 이것은 해커들이 관심을 갖는지 시험하는 방법이 되고 있다. 온라인 문서도 있어야 할 것이다. 사실, 책은 온라인 문서에서 시작될 수 있다. 하지만 아직은 들고 다니는 책이 구식이라고 생각되지 않는다. 책이라는 형식은 편리하며, 출판사가 가하는 사실상의 검열은 완벽하지만 않으면 유용한 여과 장치가 된다. 서점은 새로운 언어에 대해 배울 수 있는 중요한 곳이다. == 간결함 == 어떤 언어에든 필요한 세 가지, 즉 그 언어로 구현된 무료 제품, 책, 해킹할 어떤 것을 공급할 수 있다면, 이제 해커들이 좋아할 언어를 어떻게 만들 것인가? 해커들이 좋아하는 한 가지는 간결함이다. 해커들은 게으르다. 수학자들이나 현대 건축가들이 게으른 것과 마찬가지이다. 그들은 불필요한(extraneous) 것들을 아주 싫어한다. 어떤 프로그램을 작성하려는 해커가, 최소한 잠재의식에 의해서, 타자해야 하는 문자들의 총 개수에 근거하여 어떤 언어를 쓸지 결정한다고 해도 크게 틀린 말은 아닐 것이다. 해커들이 정말로 이렇게 생각하지는 않는다 해도, 정말 그렇다고 간주하고 언어를 고안한다면 좋은 결과를 얻을 수 있을 것이다. 일상 언어를 닮은 장황한 식(expression)을 통해 사용자를 어린아이 취급하려고 한다면 그것은 실수하는 것이다. 해커에게 다음과 같이 쓰는 대신 z = x+y 다음과 같이 쓰라고 한다면 add x to y giving z 그는 이것을 자기 지능에 대한 모욕과 신에 대한 범죄의 중간쯤 되는 것으로 여길 것이다. 리스프는 때때로 car와 cdr 대신에 first(처음)와 rest(나머지)를 써야 한다는 말을 들어 왔다. 그것이 프로그램을 읽기 쉽게 할 것 같기 때문이다. 아마 처음 몇 시간은 그럴 것이다. 하지만 해커라면 car가 리스트(list)의 처음 요소를 뜻하고 cdr가 나머지를 뜻한다는 것 정도는 신속하게 배울 수 있다. first와 rest를 쓴다는 것은 타자를 50% 더 해야 되는 것을 의미한다. 그리고 그것은 길이도 달라서, car와 cdr가 보통 그렇게 쓰이듯이 여러 줄에 잇달아 호출될 때 인자(argument)들이 한 줄로 정렬되지 않을 것이다. 나는 코드가 종이 위에 어떻게 정렬되는가 하는 것도 상당히 중요하다는 것을 발견했다. 나는 리스프 코드가 가변폭 폰트로 작성되면 그것을 거의 읽을 수 없는데, 친구들도 말하기를 이것은 다른 언어에서도 사실이라고 한다. 간결함은 자료형 검사가 엄격한 언어(strongly typed language)들이 놓치고 있는 점이다. 다른 조건이 모두 같다면, 아무도 선언문(declaration)이 무더기로 나오는 프로그램을 시작하고 싶지 않을 것이다. 무엇을 암묵적으로 할 수 있다면 그렇게 해야 한다. 각 토큰(token)들도 역시 짧아야 한다. 펄과 커먼 리스프는 이 문제에 대해 극과 극을 달린다. 펄 프로그램은 거의 암호처럼 압축시킬 수도 있지만, 커먼 리스프의 내장 연산자(built-in operator)들의 이름은 우스꽝스럽게 길다. 커먼 리스프를 고안한 사람들은 사용자들이 이 긴 이름들을 대신 타자해 주는 텍스트 편집기를 갖고 있을 것이라고 기대했는지도 모른다. 하지만 긴 이름에 드는 비용은 그것을 타자하는 데 드는 비용만이 아니다. 그것을 읽는 비용도 있고, 그것이 화면에서 차지하는 공간의 비용도 있다. == 해킹 가능 == 해커에게 간결함보다 더 중요한 것이 하나 있다. 원하는 것을 할 수 있어야 한다는 것이다. 프로그래밍 언어의 역사 속에서 프로그래머들이 부적절하다고 여겨지는 일들을 못 하게 막으려는 노력을 놀라울 정도로 많이 볼 수 있다. 이것은 위험할 만큼 주제넘은 생각이다. 언어 설계자들이 어떻게 프로그래머가 무엇을 원하게 될지 알 수 있는가? 언어 설계자들은 대상 사용자가, 혼자 걸려 넘어지지 않게 보호해 줘야 할 얼뜨기가 아니라, 전혀 예측하지 못한 무엇인가를 요구할 천재라고 생각하는 것이 더 나을 것 같다. 얼뜨기는 결국에는 자기 발을 찍게 될 것이다. 그가 다른 패키지의 변수들을 참조하지 못하게 도와줄 수는 있겠지만, 그가 잘못 짚은 문제를 해결하기 위해 형편없이 설계된 프로그램을 작성하거나 평생 그 일만 붙잡고 있지 않게 도와줄 수는 없을 것이다. 좋은 프로그래머들은 종종 위험스럽고 냄새나는 일들을 하고 싶어 한다. 냄새나는 일이란, 그 언어가 제공하려는 의미구조(semantics)의 겉모양 뒤에 숨어있는 것을 말한다. 예를 들어, 어떤 상위 수준의 추상화에 대한 내부의 데이터 표현 방식(representation)을 파악하는 것을 말한다. 해커들을 해킹을 좋아한다. 해킹이란 속으로 파고드는 것이며 처음 고안한 사람의 생각을 알아내는 것이다. ''자기의 생각을 알아내도록 허용하라.'' 어떤 도구가 만들어지면, 사람들은 그것을 원래 의도하지 않았던 방식으로 사용하는데, 이것은 특히 프로그래밍 언어와 같이 기능 구분이 확실한 도구에서도 사실이다. 많은 해커들이 그 의미구조(semantics)의 모형을 상상도 못한 방식으로 비틀어(tweak) 보고 싶어 한다. 다시 말하는데, 그렇게 하게 하라. 프로그래머가, 가비지 수집기(garbage collector) 같은 실행(runtime) 시스템을 위험에 빠뜨리지 않는 한도 내에서, 내부의 것들에 속속들이 접근할 수 있게 하라. 나는 커먼 리스프를 쓰면서 구조체(struct)의 필드들을 차례대로 읽고(iterate) 싶을 때가 있었다. 예를 들어, 삭제된 객체들에 대한 참조(reference)를 걸러 내기 위해서, 또 초기화되지 않은 필드들을 찾아내기 위해서이다. 나는 구조체가 내부적으로 벡터(vector)일 뿐인 것을 안다. 하지만 나는 아무 구조체나 호출할 수 있는 다목적 함수를 작성할 수 없다. 나는 그 필드들을 이름으로만 접근할 수 있다. 그것이 구조체가 의미하는 바이기 때문이다. 해커는 어떤 큰 프로그램에 들어있는 것들의 의도된 모형을 한두 번 뒤엎는 것을 원하기만 할 수도 있다. 하지만 실제 그렇게 할 수 있다는 것은 얼마나 큰 차이가 있는가. 이것은 어떤 문제를 해결할 수 있는가의 문제 이상일 수 있다. 여기에는 일종의 즐거움도 있다. 해커들은 빽빽한 내장을 헤집는 외과 의사의 은밀한 즐거움과 여드름을 터뜨리는 십대의 은밀한 즐거움을 공유한다. ''주: '바람이 뇌를 스칠 때 (When the Air Hits Your Brain)'라는 글에서 신경외과 의사인 프랭크 버토식(Frank Vertosick)은 외과 의사와 내과 의사("벼룩")의 차이에 대해 자신의 수석 전공의(chief resident)인 게리(Gary)와 나눈 대화에 대해 자세히 이야기하고 있다.'' ''게리와 나는 큰 피자를 주문하고 빈 자리를 찾았다. 그가 담배에 불을 붙였다. "저 빌어먹을 벼룩들 좀 보세요. 평생 한 번이나 볼 것 같은 질병에 대해 재잘거리고 있잖아요. 그게 벼룩들의 문제예요. 걔들은 별난 것들만 좋아해요. 걔들은 앞으로 그걸로 먹고 살아야 하는 사례들은 싫어해요. 그게 우리와 저 벼룩 자식들의 차이죠. 보세요. 우리는 큼직하고 군침 도는(juicy) 허리 디스크(lumbar disc herniations)를 좋아하는데, 걔들은 고혈압을 싫어해요."'' ''허리 디스크가 군침 돈다고 생각하기는 어렵다. 그래도 나는 그들이 무슨 말을 하는지 알 것 같다. 나도 종종 추적해야 하는 군침 도는 버그를 만나곤 한다. 프로그래머가 아닌 사람은 버그에 무슨 즐거움이 있는지 상상하기 어려울 것이다. 분명히 모든 것이 제대로 동작하면 더 좋다. 어떤 면에서는 그렇다. 하지만 그래도 어떤 종류의 버그들을 사냥하는 것에는 엄연한 만족이 있다는 것을 부인할 수 없다.'' 최소한 소년들에게는 어떤 종류의 공포가 매혹적이기도 하다. 남성지인 맥심(Maxim)은 미녀 모델과 섬뜩한 사고가 섞여 있는 사진집을 매년 출판한다. 독자가 누구인지 잘 아는 것이다. 역사적으로, 리스프는 해커들이 자기 방식대로 해 나가기에 좋았다. 커먼 리스프의 정치적 공정함(political correctness)은 본궤도를 벗어난 것이다. 초창기의 리스프는 모든 것에 손을 댈 수 있게 허용했다. 그 정신의 많은 부분은, 다행스럽게도, 매크로 기능에 남아 있다. 소스 코드를 임의로 변형시킬 수 있다는 것은 얼마나 멋진 일인가. 고전적 매크로는 진정한 해커의 도구이다. 단순하고 강력하고 위험하다. 그것이 어떻게 동작하는지 이해하기는 아주 쉽다. 즉, 매크로의 인자(argument)들을 받는 어떤 함수를 호출하고, 거기에서 반환된 것이 그 매크로 호출 대신 삽입된다. 위생적인(hygienic) 매크로는 이것과 반대의 원리로 구현된다. 그것이 어떻게 동작하는지 이해할 필요 없도록 사용자를 보호하려고 한다. 나는 위생적인 매크로에 대한 설명이 한 줄이라도 있다는 말을 들어 본 적이 없다. 이것은 프로그래머들에게 원할 것과 원하지 말 것을 결정해 주는 것의 위험을 보여 주는 고전적인 사례이다. 위생적인 매크로는, 많은 것 가운데, 변수 포획(variable capture)에서 나를 보호하려고 하지만, 어떤 매크로에서는 변수 포획이 바로 내가 원하는 것이다. 진정으로 좋은 언어는 깨끗하면서 지저분해야 한다. 즉, 잘 이해될 수 있고 서로 독립적인(orthogonal) 연산자들로 이뤄진 작은 핵심(core) 구조로 깨끗하게 설계되어야 하지만, 해커들이 자기 방식대로 쓸 수 있게 한다는 의미에서 지저분해야 한다. C가 여기에 가깝다. 초창기 리스프도 그랬다. 진정한 해커의 언어는 항상 약간의 건달(raffish) 끼가 있는 것 같다. 좋은 프로그래밍 언어는 "소프트웨어 공학"이라는 용어를 쓰는 사람들이 안 된다며 고개를 젓게 하는 특징들이 있어야 한다. 이 연속선의 반대편에는 에이다(Ada)나 파스칼(Pascal) 같은 언어가 있다. 이들은 예의바름(propriety)의 모범이라서 학교에서 가르치는 데는 좋지만 그 외에는 별로 좋은 것을 모르겠다. == 일회용 프로그램 == 해커들에게 매력적인 언어는 그들이 작성하고 싶은 다양한 프로그램들을 작성하기에 좋아야 한다. 이 말은, 어쩌면 놀랍게 들리겠지만, 일회용(throwaway) 프로그램을 작성하기에 좋아야 한다는 말이다. 일회용 프로그램이란 어떤 한정된 작업을 위해 신속하게 작성해야 하는 프로그램이다. 즉, 어떤 시스템 관리 작업을 자동화하거나 모의실험(simulation)을 위한 시험 데이터를 만들어 내거나 데이터를 이 형식에서 다른 형식으로 변환하는 프로그램이 그것이다. 일회용 프로그램의 놀라운 점은, 제2차 세계대전 중 많은 미국 대학들에 세워진 "임시" 건물들이 아직도 남아 있는 것처럼, 그것이 종종 버려지지 않는다는 것이다. 많은 수가 실제 기능과 실제 사용자가 있는 실제 프로그램으로 발전한다. 나는 최고의 대형 프로그램들이, 후버 댐(Hoover Dam)처럼 처음부터 크게 설계된 것이 아니라, 이런 식으로 탄생한 것 같다는 느낌이 든다. 무엇인가를 무에서부터 만들어 간다는 것은 끔찍한 일이다. 사람들은 너무 큰 프로젝트를 맡으면 기가 질리고 만다. 그 프로젝트는 수렁에 빠져 버리거나 그 결과가 메마르고 생기 없게 된다. 진정한 도심지 대신 상점가, 로마 대신 브라질리아, C 대신 에이다(Ada)가 되는 것이다. 대형 프로그램을 만드는 다른 방법은, 일회용 프로그램에서 출발하여 그것을 개선해 가는 것이다. 이런 접근 방법은 기가 꺾이는 일이 덜하고, 그 프로그램의 설계는 진화의 혜택을 입을 수 있다. 잘 살펴본다면 대부분의 대형 프로그램이 이런 방식으로 개발됐다는 것이 밝혀질 것이라고 생각된다. 그리고 이런 방식으로 발전한 프로그램들은, 정치적인 이유가 아니라면 다른 시스템으로 이식되는(ported) 일은 드물기 때문에, 여전히 그것들이 처음 작성된 그 언어로 작성되고 있을 것이다. 그러므로 역설적이게도, 대형 시스템에서 쓰일 언어를 만들고 싶다면, 일회용 프로그램을 작성하기 좋게 만들어야 하는 것이다. 그런 프로그램에서 대형 시스템이 나오기 때문이다. 펄은 이런 생각이 실현된 두드러진 사례이다. 펄은 일회용 프로그램을 작성하기 위해서 고안되었을 뿐만 아니라, 그것 자체가 일회용 프로그램이었다. 펄은 보고서를 생성하기 위해 필요한 유틸리티 모음으로 탄생했다가, 사람들이 그것으로 작성한 일회용 프로그램들이 점점 늘어나면서 프로그래밍 언어로 발전한 것이다. 적어도 펄 5가 되어서야 이 언어는 제대로 된 프로그램을 작성하기에 적합했지만, 그럼에도 불구하고 이미 막대한 인기를 얻고 있었다. 일회용 프로그램을 만들기 위해 좋은 언어는 어때야 하는가? 우선은, 그것은 언제나 쓸 수 있어야(available) 한다. 일회용 프로그램은 한 시간에 다 작성할 만한 것이다. 따라서 그 언어는 사용하는 컴퓨터에 이미 설치되어 있어야 할 것이다. 사용 전에 먼저 설치를 해야 한다면 틀린 것이다. 이미 거기에 있어야 한다. C는 거기 있었다. 운영체제와 함께 왔기 때문이다. 펄도 거기 있었다. 원래 시스템 관리를 위한 도구였고 컴퓨터에 이미 설치되어 있었기 때문이다. 하지만 쓸 수 있다는 것은 설치되어 있다는 것 이상의 의미이다. 명령행(command-line) 환경의 대화식(interactive) 언어는 컴파일과 실행을 따로 해야 하는 것보다 더 잘 쓸 수 있는 것이다. 인기 있는 프로그래밍 언어는 대화식이어야 하고, 빨리 시작돼야 한다. 일회용 프로그램에 바라는 다른 하나는 간결함이다. 간결함은 해커들에게는 언제나 매력적이지만, 그들이 한 시간에 만들어낼 만한 프로그램 안에서는 더더욱 그렇다. == 라이브러리 == 물론 궁극적인 간결함(brevity)은 이미 그 목적으로 작성된 프로그램이 있어서 그것을 호출하기만 하면 되는 것을 말한다. 이것은 프로그래밍 언어에서 점점 중요한 특성이 될 것으로 생각되는 어떤 것으로 이어진다. 라이브러리 함수가 그것이다. 펄은 문자열 처리를 위한 방대한 라이브러리가 있기 때문에 성공했다. 이런 종류의 라이브러리 함수들은, 주로 데이터를 변환하거나 추출하기 위해 작성되기 시작하는 일회용(throwaway) 프로그램에서 특히 중요하다. 많은 펄 프로그램들이 라이브러리 호출 몇 개를 묶어 놓은 것에서 시작됐을 것이다. 나는 앞으로 50년 동안 프로그래밍 언어에 나타날 진보된 모습들 중 많은 부분이 라이브러리 함수와 상관있을 것이라고 생각한다. 미래의 프로그래밍 언어는 핵심 언어 부분처럼 주의 깊게 고안된 라이브러리를 갖추게 될 것이라고 생각한다. 프로그래밍 언어를 고안하는 일이, 그 언어가 자료형 검사를 엄격하게 하는가, 느슨하게 하는가, 객체 지향인가, 함수형(functional)인가 하는 문제가 아니라, 어떻게 훌륭한 라이브러리를 설계할 것인가의 문제가 될 것이다. 자료형 체계(type system)를 어떻게 설계할까 고민하기 좋아하는 부류의 언어 설계자들은 이 말에 몸서리를 칠 것이다. 이것은 거의 응용프로그램을 작성하는 것과 같지 않은가! 참 안됐다. 하지만 언어는 프로그래머를 위한 것이며, 라이브러리는 프로그래머가 원하는 것이다. 좋은 라이브러리를 설계하는 것은 어려운 일이다. 이것은 코드만 많이 작성한다고 되는 일이 아니다. 라이브러리가 너무 커진다면, 필요한 함수를 직접 작성하는 것보다 그것을 찾는 데 시간이 더 걸릴 수도 있을 것이다. 라이브러리는, 핵심 언어 부분과 똑같이, 서로 독립적인(orthogonal) 최소한의 연산자들을 써서 설계되어야 한다. 그리고 필요한 일을 위해서 라이브러리 호출을 하면 어떤 결과를 얻을 수 있을지 프로그래머가 추측할 수 있어야 한다. 라이브러리는 커먼 리스프가 놓치고 있는 것이다. 문자열 처리를 위한 기초적인 라이브러리만 있고 운영체제에 접근하기 위한 것은 거의 없다. 역사적인 이유로 커먼 리스프는 OS가 존재하지 않는 것처럼 동작하려고 한다. OS에 접근할 수 없기 때문에, 커먼 리스프에 내장된 연산자만 써서는 제대로 된 프로그램을 작성할 수 없게 된다. 구현된 시스템 특유의(implement-specific) 해킹을 해야 할 경우도 있는데, 실제로는 이렇게 한다고 해서 원하는 것을 모두 얻을 수 있는 것도 아니다. 커먼 리스프가 문자열 라이브러리가 강력하고 OS 지원을 잘 했다면 해커들은 리스프에 대해 더욱 높게 평가했을 것이다. == 문법 == 문법이 리스프와 같은 언어, 좀 더 엄밀히 말해서 문법이 없는 언어가 인기 있게 될 수 있을까? 나는 이 물음에 대한 답을 잘 모르겠다. 하지만 리스프가 현재 인기가 없는 것이 문법 때문만이라고는 생각하지 않는다. 커먼 리스프는 생소한 문법보다 더 큰 문제가 있다. 앞 표기 문법(prefix syntax)을 편하게 쓸 수 있어도 강력한 문자열 라이브러리와 OS에 대한 접근성 때문에 기본적으로 펄을 쓰는 프로그래머들도 있다. 앞 표기 문법은 두 가지 정도의 문제가 있다. 프로그래머들에게 생소하다는 것과 축약적이지(dense) 않다는 점이다. 리스프 세계에서 내려오는 지혜에 따르면 첫 번째 문제가 진짜 문제라고 한다. 하지만 정말 그런지는 모르겠다. 물론, 앞 표기법(prefix notation)은 평범한 프로그래머들을 당황하게 한다. 하지만 평범한 프로그래머들의 의견이 중요하다고 생각하지는 않는다. 특급 해커(expert hacker)들이 그 언어에 대해 어떻게 생각하는가에 따라 언어가 인기 있게도 되고 없게도 되는데, 특급 해커라면 앞 표기법 정도는 잘 다룰 수 있을 것이라고 생각한다. 펄 문법도 거의 이해 불가에 가까웠지만, 그 문제가 펄의 인기를 가로막지는 못했다. 오히려 그 문제는 펄이 컬트(cult)가 되게 하는 데 도움이 됐을 것이다. 더 심각한 문제는 앞 표기법의 장황함(diffuseness)이다. 특급 해커에게도 이것은 사실 문제이다. 아무도 a[x, y]라고 쓸 수 있는 것을 (aref a x y)라고 쓰고 싶지는 않을 것이다. 이런 특별한 경우에 대해 그 문제에서 벗어날 수 있는 묘책이 있다. 자료 구조를 첨자(index)들에 대한 함수라고 간주하면, (a x y)라고 대신 쓸 수 있다. 이것은 펄의 형태보다 더 짧기까지 하다. 이런 식의 묘책을 써서 다른 형식의 표현식들도 짧게 할 수 있다. 괄호가 많이 쓰이는 것도, 들여쓰기가 의미를 갖게 함으로써 없애버릴 (혹은 안 써도 되게 할) 수 있다. 사실 프로그래머들은 이런 식으로 코드를 읽는다. 들여쓰기는 이런 뜻이고 분리자(delimiter)는 저런 뜻이라면, 우리는 들여쓰기가 맞는다고 생각한다. 들여쓰기가 의미를 갖게 하면, 이런 흔한 버그의 원인도 없애고 프로그램도 더 짧게 만들 수 있을 것이다. 때로는 사이 표기 문법(infix syntax)이 읽기 쉽다. 수학식에서는 특히 그렇다. 나는 평생 리스프로 프로그래밍을 해 왔지만, 지금도 앞 표기 수학식은 자연스러워 보이지 않는다. 하지만, 인자가 몇 개라도 상관없는 연산자가 있다는 것은 특히 코드를 생성할 때 편리하다. 리스프에 사이 표기 문법이 있다면, 그것은 일종의 읽기매크로(read-macro)로서 구현될 것이다. ''역자 주: 읽기매크로란 리스프의 '(작은따옴표)와 같이 프로그램의 읽기 시간에 (즉 가장 먼저) 처리되는 매크로이다. 일반 매크로는 컴파일 시간에, 함수는 실행 시간에 처리된다.'' 잘 이해되는 방식에 의해 원래의 S식(s-expression)으로 번역될 수 있다면, 우리가 종교적 신념처럼 리스프에 문법을 도입하는 것을 반대해야 한다고 생각하지는 않는다. ''역자 주: S식이란 심벌(symbol)과 그것을 묶는 괄호로 데이터나 함수를 표현하는 식을 말한다. 여기서 S는 심벌(symbolic)을 뜻한다.'' 이미 리스프에는 문법이 많이 있다. 추가 도입하는 것이 필연적으로 나쁘다고 할 수는 없다. 단, 그것을 쓰라고 강요해서는 안 된다. 커먼 리스프에서는 어떤 분리자(delimiter)들이 사용 제한되어(reserved) 있다. 이것은 최소한 어떤 설계자들이 나중에 문법을 추가로 도입할 의도가 있다는 것을 암시한다. 커먼 리스프에서 가장 터무니없이 리스프답지 않은 문법은 형식 지정 문자열(format string)에서 볼 수 있다. 이 형식 지정 방식은 독립된 새로운 언어였고 그 언어는 리스프가 아니다. 리스프에 새로운 문법을 도입할 계획이라면 형식 지정자(format specifier)들도 리스프의 일부가 될 수 있을 텐데 말이다. 매크로로 다른 종류의 코드를 생성하듯이 형식 지정자도 그렇게 생성할 수 있었다면 좋았을 것이다. 어떤 뛰어난 리스프 해커가 나에게 그가 갖고 있는 CLTL은 형식 지정(format) 절이 저절로 펼쳐진다고 말했다. ''역자 주: 가이 L. 스틸(Guy L. Steele)의 책 "Common Lisp the Language".'' 내 것도 마찬가지이다. 이것은 개선의 여지가 있음을 나타내는 것이다. 이것 때문에 프로그램에 입출력(I/O)이 많아진다는 의미일 수도 있다. == 효율 == 좋은 언어는, 모두들 알다시피, 빠른 코드를 생성해 내야 한다. 하지만 실제로는 빠른 코드가 언어의 설계에 들인 노력에서 나오는 것 같지는 않다. 커누쓰(Knuth)가 오래 전에 지적했듯이, 속도는 어떤 결정적인 병목(bottleneck)에서나 중요할 뿐이다. 그 후에도 많은 프로그래머들이 깨달아 왔듯이, 사람들은 이런 병목이 어디에 있는지에 대해 종종 오해하곤 한다. 그래서 실제로는 빠른 코드를 얻는 방법은 좋은 성능 분석 도구(profiler)를 갖추는 것이지, 이를테면 자료형 검사가 엄격한 언어로 되는 것이 아니다. 프로그램의 모든 호출에 등장하는 모든 인자들의 자료형을 알 필요는 없다. 인자들의 자료형을 선언할 수 있어야 하는 것은 병목에서이다. 그리고 더욱 중요한 것은 병목이 어디인지 알아낼 수 있어야 한다. 사람들이 리스프에 대해 갖는 불만 하나는 프로그램에서 어느 부분이 낭비적(expensive)인지 구분하기 힘들다는 것이다. 사실인지도 모른다. 매우 추상적인 언어가 필요하다면 어쩔 수 없는 것일 수도 있다. 어느 경우이든 성능 분석을 잘 하는 것이 그 프로그램을 고치는 데에 더욱 효과가 있을 것이라고 생각한다. 이것을 통해 어느 부분이 낭비적인지 금방 알 수 있을 것이다. 그 문제는 일부 사회적인 문제이기도 하다. 언어 설계자들은 빠른 컴파일러를 작성하고 싶어 한다. 그들은 그렇게 자신의 기능을 가늠해 본다. 그들은 성능 분석 도구는 기껏해야 부록(add-on)쯤으로 생각한다. 하지만 실제로는 빠른 코드를 생성하는 컴파일러보다, 좋은 성능 분석 도구가 그 언어로 작성된 실제 프로그램들의 속도를 향상시키는 데에 더 크게 기여할 수 있다. 여기에서도 언어 설계자들은 그 언어 사용자들의 사정에 다소 어두운 것 같다. 그들은 잘못 짚은 문제를 겨우 조금 해결하기 위해 정말로 열심히들 일하는 것 같다. 적극적인 성능 분석 도구, 즉 프로그래머가 성능 자료들을 요청할 때까지 기다리고 있는 것이 아니라 보라고 독촉하는(push) 것을 마련하는 것도 좋을 것이다. 예를 들어, 프로그래머가 소스 코드를 편집할 때, 편집기에서 병목들을 빨갛게 표시할 수 있을 것이다. 또 다른 방법으로는, 프로그램을 실행할 때 무슨 일이 일어나는지 어떤 식으로든 표시하게 할 수 있을 것이다. 이것은 살펴봐야 하는 실행 중인 프로그램이 많은 서버 기반 응용프로그램들에서 특히 큰 성공을 거둘 것이다. 적극적인 성능 기록 도구는 프로그램 실행 중에 메모리에서 무슨 일이 일어나는지 그림으로 보여 주거나, 무슨 일이 있는지 알려주는 소리를 낼 수도 있다. 소리는 문제 발생을 알리는 신호로서 좋다. 내가 일했던 곳에는 우리 웹 서버들에서 무슨 일이 있는지 보여주는 큰 눈금판이 있었다. 그 지침은 조그만 서보모터(servomotor)로 돌아갔는데 돌아갈 때 작은 잡음이 들렸다. 내 책상에서 그 눈금판을 볼 수 없어도 나는 그 소리에 의해 언제 서버에 문제가 생겼는지 즉시 알 수 있었다. 자동적으로 비효율적인 알고리듬을 간파하는 성능 분석 도구를 직접 작성하는 것도 가능할 것이다. 특정한 메모리 접근 방식이 안 좋은 알고리듬을 나타내는 분명한 신호임이 밝혀진다 해도 그렇게 놀랄 일은 아닌 것 같다. 컴퓨터 속에서 돌아다니며 우리 프로그램을 실행하는 작은 사람이 있다면, 그는 공무원으로 일하는 자신의 길고도 슬픈 얘기를 우리에게 들려주고 싶어 할지도 모른다. 가끔 나는 프로세서에게 쓸데없는 일(wild-goose chase)을 너무 많이 시키고 있는 것 같다는 느낌을 받지만, 그것이 무엇을 하고 있는지 살펴 볼 좋은 방법은 아직 못 찾았다. 지금 많은 리스프에서는 바이트 코드가 컴파일 되고, 그것이 인터프리터로 실행된다. 이렇게 하는 것은 보통 다른 시스템으로 쉽게 이식하기 위해서이다. 그런데 이런 특징은 언어로서도 유용한 것이다. 바이트 코드를 언어의 공식 부분으로 만들고, 프로그래머가 병목에서 인라인 바이트 코드를 쓸 수 있게 하는 것도 좋을 것 같다. 그렇게 되면 이렇게 최적화한 것이 다른 시스템에도 이식될 수 있을 것이다. 속도의 성격은 최종 사용자가 느끼는 것에 따라 사람마다 다를 수 있다. 서버 기반 응용프로그램들이 융성하면서, 점점 더 많은 프로그램들이 입출력(I/O)에 큰 영향을 받게 될 것이다. 입출력을 빠르게 하는 것이 가치 있게 될 것이다. 이것은 간결하고 빠르고 형식이 정해진 출력 함수와 같은 직접적인 방법에 의해 도움이 될 수도 있고, 캐시(caching)나 영속 객체(persistent object)와 같이 근본적인 구조 변화로써 그렇게 할 수도 있다. 사용자들은 반응 시간에 관심을 갖는다. 하지만 또 다른 종류의 효율이 점점 더 중요해질 것이다. 프로세서마다 지원할 수 있는 동시 사용자 수가 그것이다. 머지않아 만들어질 많은 흥미로운 응용프로그램들이 서버 기반이 될 것이고, 그런 응용프로그램을 불러 쓰는(hosting) 사람들은 서버당 사용자 수에 대해 결정적으로 궁금해 할 것이다. 서버 기반 응용프로그램 제공 사업의 주요 비용에서 이 수는 분모(divisor)가 된다. 여러 해 동안 효율은 최종 사용자의 응용프로그램들 대부분에서 별 문제가 되지 않았다. 개발자들은 각 사용자가 점점 더 강력해져 가는 프로세서를 갖추고 자기 자리에 앉아 있다고 가정해도 무방했다. 파킨슨(Parkinson)의 법칙에 따라 소프트웨어는 쓸 수 있는 모든 공급원을 다 쓰도록 확대되어 왔다. ''역자 주: 파킨슨의 법칙이란 "일은 그것이 완료될 때까지 채울 수 있는 모든 시간을 다 채우도록 확대된다"는 관료주의에 관한 법칙. 해커들은 이 법칙을 "데이터는 저장 매체의 여유 공간을 다 채울 때까지 확대된다"는 파킨슨의 "데이터" 법칙으로 변형시켰다.'' 이것은 서버 기반 응용프로그램의 등장에 따라 달라질 것이다. 그 세계에서는 하드웨어와 소프트웨어가 같이 공급될 것이다. 서버 기반 응용프로그램을 제공하는 회사로서는 서버당 얼마나 많은 사용자를 지원할 수 있는가에 따라 순이익(bottom-line)에 큰 차이가 생길 것이다. 어떤 응용프로그램에서는 프로세서가 제한 요인이 되고 실행 속도가 최적화에 가장 중요한 것이 된다. 하지만 메모리가 제한 요인이 되기도 한다. 동시 사용자 수는 각 사용자 데이터에 필요한 메모리의 양으로 결정된다. 언어가 여기에서도 도움이 될 수 있다. 쓰레드가 잘 지원되면 모든 사용자가 단일한 힙(heap)을 공유할 수 있을 것이다. 영속 객체(persistent object)나 언어 수준에서 느긋한 적재(lazy loading)를 지원하는 것도 도움이 된다. ''역자 주: 느긋한 적재(lazy loading)란 모듈을 미리 올리지 않고 함수가 호출될 때 관련 모듈을 올리는 것을 말한다.'' == 시간 == 인기 있는 언어에 필요한 마지막 성분은 시간이다. 아무도 사라져 버릴지 모르는 언어로 프로그램을 작성하고 싶어 하지 않는다. 사실 많은 프로그래밍 언어들이 사라졌다. 그래서 해커들은 대부분 이삼 년 정도 어떤 언어의 활약을 지켜본 뒤에야 그것을 한 번 써 볼까 하고 생각하는 경향이 있다. 멋진 새 발명품을 만든 사람들은 이 사실을 알고 놀라곤 하지만, 어떤 정보가 사람들에게 충분히 알려지는 데에는 시간이 걸린다. 내 친구 하나는 요청 한 번에 바로 일을 시작하는 경우가 거의 없다. 그는 사람들이 무엇을 요청하더라도 알고 보면 그것이 그렇게 원하는 것은 아니라는 사실을 잘 안다. 시간 낭비를 피하기 위해, 그는 그 일에 대해 서너 번 요청이 있을 때까지 기다린다. 그 정도 되면 그에게 요청한 사람은 기분이 나빠지겠지만, 최소한 그들이 그 일을 정말로 원한다는 사실은 드러나는 것이다. 대부분의 사람들은 새로운 것에 관해 듣게 될 때 이와 비슷하게 걸러내는 방법을 익혀 왔다. 그들은 어떤 것에 대해 열 번 이상 듣기 전에는 그것에 관심조차 갖지 않는다. 그들의 행동은 너무나도 정당하다. 방금 나온 최신의 것들 대부분은 시간 낭비로 밝혀지고 결국 사라져 버리기 때문이다. 나는 VRML 배우는 일을 미뤄 둠으로써 그 일을 아예 하지 않아도 되었다. 그래서 새로운 것을 발명한 사람은 사람들이 관심을 갖기 시작할 때까지 몇 년이고 정보를 계속 반복해서 알려야 하는 것이다. 우리는, 내가 아는 한, 최초의 웹 서버 기반 응용프로그램을 작성했는데, 사람들에게 그것을 내려받지 않아도 된다는 사실을 충분히 알리는 데에만 몇 년이 걸렸다. 이것은 사람들이 멍청해서가 아니다. 그들은 우리에 대한 관심을 꺼 놓았을 뿐이다. 그래도 기쁜 소식은 단순한 반복이 문제를 해결한다는 사실이다. 오로지 해야 하는 일은 자신의 이야기를 계속 들려주는 것이다. 결국 사람들은 귀를 기울이게 될 것이다. 사람들이 관심을 갖게 되는 때는, 내가 거기 있다는 것을 알게 되었을 때가 아니라, 내가 아직도 거기 있다는 것을 알게 되었을 때이다. 사람들을 움직이는 것도 마찬가지로 시간이 필요하다. 대부분의 기술들은 처음 등장한 이후에도 상당히 발전해 간다. 프로그래밍 언어는 특히 그렇다. 새로운 기술은 몇 년 동안 소수의 선각수용자(early adopter)들만 사용하게 하는 것이 가장 좋다. 선각수용자들은 섬세하고 요구가 많으며, 그 기술에 남아있는 흠들을 바로바로 쏟아낸다. 소수의 사용자들만 있을 때에는 그들 모두와 가깝게 지낼 수 있다. 선각수용자들은 시스템이 손상을 일으켜도 그것이 개선되어 간다면 너그러워진다. 새로운 기술이 소개되는 두 가지 방법이 있다. 생장법(organic growth)과 빅뱅법(big bang)이 그것이다. 생장법은 육감에 의해(seat-of-the-pants) 충분한 자금도 없이 창고에서 시작하는 고전적인 방식을 예로 들 수 있다. 두세 명이 모여 알아주는 이도 없이 일하면서 어떤 새로운 기술을 개발한다. 마케팅 전략도 없이 출시하고 소수의 (열광적으로 헌신된) 사용자들만 얻는다. 그들은 그 기술을 계속 개선해 가며, 그 동안 소문을 타고 사용자 기반이 커져 간다. 그들이 알지 못하는 사이에 그들은 커져 있다. 다른 접근 방식인 빅뱅법은 벤처자금(VC)을 등에 업고 대규모의 마케팅 전략으로 시작하는 것을 예로 들 수 있다. 그들은 제품 개발을 향해 돌진하여 대중의 주목을 받으며 출시하고 즉시 (그들이 바라기로는) 대규모의 사용자 기반을 이룬다. 일반적으로 창고형 사람들은 빅뱅형 사람들을 부러워한다. 빅뱅형 사람들은 세련되고 자신만만하며 벤처투자자들의 인정을 받는다. 그들은 모든 것을 최고급으로 누릴 수 있고, 출시에 맞춘 제품설명회(PR campaign)를 통해 유명인사가 되는 부수 효과까지 얻는다. 생장형 사람들은 창고에 앉아서 자기들이 불쌍하고 소외되었다고 느낀다. 하지만 나는 그들이 스스로 가엾게 여기는 것은 오해일 경우가 많다고 생각한다. 생장법은 빅뱅법보다 더 나은 기술과 더 풍부한 후원자(founder)들을 낳는다. 오늘날 주도적인 기술들을 보면 대부분이 생장해 왔음을 알게 될 것이다. 이러한 양식은 회사에만 적용되는 것이 아니다. 위탁 연구(sponsored research)에서도 볼 수 있다. 멀틱스(Multics)와 커먼 리스프는 빅뱅형 프로젝트였고, 유닉스와 맥리스프(MacLisp)는 생장형 프로젝트였다. ''역자 주: 멀틱스(Multiplexed Information and Computing Service)는 1965년 미국의 MIT, 제너럴 일렉트릭(GE), 벨연구소가 공동으로 개발한 메인프레임용 시분할(timesharing) 운영체제이다. 2000년 10월 30일 캐나다 국방부의 멀틱스 시스템이 종료되면서 멀틱스로 운영되는 시스템은 전세계에 하나도 남지 않게 되었다. http://www.multicians.org/history.html'' == 재설계 == E. B. 화이트(White)는 "가장 좋은 글쓰기는 고쳐 쓰기(rewriting)"라고 했다. ''역자 주: 미국의 동화 작가. "스튜어트 리틀(Stuart Little)" 등의 작품을 썼다.'' 좋은 작가들은 모두 이것을 잘 알고 있으며, 이것은 소프트웨어에 대해서도 진실이다. 설계에서 가장 중요한 부분은 재설계(redesign)이다. 프로그래밍 언어는 특히 아무리 재설계를 해도 충분치 않다. 좋은 소프트웨어를 작성하기 위해서는 두 가지 상반된 생각을 머리 속에 동시에 갖고 있어야 한다. 자신의 능력에 대해 어린 해커와 같은 순진한 믿음이 필요하고, 그와 동시에 백전노장의 회의론(skepticism)이 필요하다. 머리의 반쪽으로는 '그게 얼마나 어렵겠어?' 하고 생각할 수 있어야 하고, 다른 반쪽으로는 '그건 안 될 거야.' 하고 생각해야 한다. 여기에는 실제로 아무 모순이 없다는 것을 깨닫는 것이 요령이다. 서로 다른 두 가지에 대해 각각 낙관적이고 회의적이 되라는 것이다. 문제를 해결할 수 있다는 가능성에 대해서는 낙관적이 되어야 하고, 지금까지 얻은 해결책의 가치에 대해서는 회의적이 되어야 한다. 일을 잘 하는 사람들은 종종 자기가 하고 있는 일이 별로라고 생각한다. 그들이 해 놓은 일을 다른 사람들은 놀라움 가득히 바라보지만, 창작자 자신은 근심이 가득하다. 이런 양태는 우연의 일치가 아니다. 이 근심은 그 일을 좋아지게 한다. 희망과 근심의 균형을 유지할 수 있다면, 두 다리가 자전거를 앞으로 추진해 가듯이, 이 둘은 프로젝트를 앞으로 추진해 갈 것이다. 이 2단계 순환 혁신 엔진(two-cycle innovation engine)의 첫 번째 단계에서는 해결할 수 있다는 확신에 고무되어 어떤 문제에 맹렬하게 달려든다. 두 번째 단계에서는 이뤄낸 것을 냉정하게 살피면서 그 흠들을 아주 분명히 알게 된다. 하지만 비판 정신이 희망을 압도하지 않는 한, 불완전한 것이 분명한 그 시스템을 보면서도 '다른 방법을 찾는 게 얼마나 어렵겠어?' 하고 생각하며 다음 순환으로 넘어간다. 이 두 힘의 균형을 유지하는 데에는 요령이 필요하다. 어린 해커들에게는 낙관론이 우세하다. 그들은 무언가를 만들면 그것이 훌륭하다고 확신하고 더 이상 개선하지 않는다. 늙은 해커들은 회의론이 우세해서 야심적인 프로젝트는 감히 맡으려고 하지 않는다. 재설계의 순환이 계속되게 하기 위한 노력은 모두 좋은 것이다. 산문(prose)은 계속 고쳐 쓰다보면 결국은 만족스럽게 될 것이다. 하지만 소프트웨어는 일반적으로 아무리 재설계를 해도 충분치 않다. 산문은 독자가 있고 소프트웨어는 사용자가 있다. 작가는 수필을 고쳐 쓴다 해도 그 글의 옛 판을 읽는 사람들이 그 글에 새로 도입된 비호환성 때문에 자기 생각이 손상됐다고 불평하지는 않을 것이다. 사용자는 양날의 검이다. 그들은 언어를 개선하는 데 도움이 될 수도 있지만, 그것을 개선하는 데 방해가 될 수도 있다. 그래서 사용자를 조심해서 선택해야 하며 그 숫자를 천천히 늘려야 하는 것이다. 사용자를 확보하는 것은 최적화를 하는 것과 같다. 그것을 늦추는 것이 현명한 일이다. 또한 일반적으로 어느 시점에서든 생각한 것 이상의 변화를 일으킬 수 있다. 변화를 일으키는 것은 반창고를 떼어내는 것과 같다. 고통은 그것을 느낀 순간 이후에는 기억일 뿐이다. 위원회에서 언어를 설계하는 것이 좋은 생각이 아니라는 것은 모두 잘 안다. 위원회에서 내놓는 설계치고 좋은 것이 없다. 하지만 위원회의 가장 큰 위험은 그들이 재설계에 방해가 된다는 것이다. 변화를 일으키는 것은 할 일이 많으므로 아무도 귀찮아지고 싶어 하지 않는다. 위원회의 결정은, 위원들 대부분이 그것을 좋아하지 않더라도, 그대로 정체되어 있는 경향이 있다. 두 명의 위원회라도 재설계 방식에 끼어들게 되어 있다. 이것은 특히 서로 다른 두 집단의 사람들이 작성한 소프트웨어들 사이의 접점(interface)에서 생긴다. 이 접점을 변경하기 위해서는 양쪽 모두 그것을 동시에 변경하는 데 동의해야 한다. 그래서 이 접점들은 전혀 변하지 않기가 쉽다. 어떤 시스템에서든 이것들이 가장 특이한(ad hoc) 부분이 되기 쉬우므로 문제가 되는 것이다. 여기서 한 가지 해결책은, 시스템의 접점들을 수직이 아니라 수평으로 설계해서, 모듈들이 항상 추상화 계층에 수직적으로 쌓이게 하는 것이다. 그러면 이 접점은 그 층들 중 하나에 속하게 될 것이다. 두 계층 중 낮은 층이 상위 계층을 작성한 언어라서 그 낮은 계층이 접점을 관할하거나, 아니면 거기에 종속된 것이어서 상위 계층이 접점을 독점할 수 있을 것이다. == 리스프 == 이 모든 것은 새로운 리스프에 희망이 있다는 것을 암시한다. 해커들이 원하는 것을 줄 수 있는 어떤 언어든 희망이 있다. 리스프도 거기에 포함된다. 해커들이 리스프의 생소함 때문에 흥미를 잃었을 것이라고 생각하는 것은 실수일지도 모른다. 이런 마음 편한 착각 때문에 리스프, 혹은 최소한 커먼 리스프의 진짜 문제를 제대로 보지 못한 것일지 모른다. 그 문제는 바로 해커들이 원하는 것을 제대로 못 할 정도로 형편없다는 것이다. 해커의 언어는 강력한 라이브러리와 해킹할 대상이 필요하다. 커먼 리스프는 둘 다 없다. 해커의 언어는 간결하고 해킹 가능해야 한다. 커먼 리스프는 그렇지 않다. 그래도 다행인 것은 리스프 자체가 아니라 커먼 리스프가 형편없다는 사실이다. 우리가 진정한 해커의 언어가 될 새로운 리스프를 개발할 수 있다면 해커들은 그것을 사용할 것이라고 생각한다. 그들은 일 잘 하는 언어라면 무엇이든 사용할 것이다. 오로지 우리가 해야 하는 일은 이 새로운 리스프가 어떤 중요한 일을 다른 언어들보다 더 잘 하도록 만들어야 한다는 것이다. 역사를 보면 용기를 얻게 된다. 시간이 흐르면서 잇따른 새로운 프로그래밍 언어들이 리스프의 특징을 점점 더 많이 차용한다. 새로 만든 언어가 리스프라도 베낄 것이 그렇게 많이 남아 있지 않다. 최근에 갓 태어난 언어인 파이썬(Python)은 사이 표기(infix) 문법이 있고 매크로가 없는 희석된(watered-down) 리스프라고 할 수 있다. 새로운 리스프는 이러한 발전 속에 자연스럽게 한 걸음 내딛게 될 것이다. 그 언어를 파이썬의 향상 판으로 부르는 것도 괜찮은 마케팅 전술일 것 같기도 하다. 그것이 리스프라고 하는 것보다 더 세련된 것처럼 들린다. 많은 사람들에게 리스프는 괄호가 많은 느린 인공지능 언어일 뿐이다. 프리츠 쿤제(Fritz Kunze) ''역자 주: 리스프 개발 환경인 알레그로 CL(Allegro CL) 등을 개발한 프란츠 회사(Franz Inc.)의 설립자''의 공식 전기에서는 L자 들어가는 단어의 언급을 조심해서 피하기도 했다. 하지만 내 추측에는 새로운 리스프를 리스프라고 부르는 것을 겁낼 것까지는 없을 것 같다. 리스프는 여전히 가장 최고의 해커들(예를 들어, 6.001을 쓰면서 그것을 이해하는 사람들)에게서 알게 모르게 많은 존중을 받고 있다. 그들이 바로 포섭해야 하는 사용자들이다. "해커가 되는 방법(How to Become a Hacker)"이라는 글에서 에릭 레이먼드(Eric Raymond)는 리스프를 라틴어나 그리스어 같은 것, 즉 실제로는 사용하지 않을 것이라도 지적인 훈련을 위해 배워야 하는 언어로 묘사했다. 리스프는 그것을 터득했을 때 얻게 될 심오한 깨달음의 훈련을 위해 배울 만한 가치가 있다. 리스프 자체를 실제로 사용하지는 않는다 해도 그 경험은 앞으로 남은 생애 동안 더 좋은 프로그래머가 되게 해 줄 것이다. 내가 리스프를 몰랐다면 이것을 읽으면서 여러 가지 질문을 하고 싶어졌을 것이다. 나를 더 좋은 프로그래머로 만들어 줄 언어는, 그것이 의미 있는 말이라면, 프로그래밍을 하는 데에도 더 좋은 언어라는 뜻이다. 그리고 그것이 사실 에릭이 말하려던 속뜻이다. 그러한 생각이 퍼지고 있는 한, 해커들은 새로운 리스프가 리스프라고 불리더라도 충분히 잘 받아들일 것이라고 생각한다. 하지만 이 리스프는 1970년대의 고전적 리스프들처럼 해커의 언어가 되어야 한다. 간결하고 단순하고 해킹 가능해야 한다. 그리고 해커들이 당장 하고 싶어 하는 것을 하기 위한 강력한 라이브러리를 갖춰야 한다. 라이브러리의 문제에 대해서는, 펄이나 파이썬과 같은 언어들을 그 고유의 영역에서 뛰어넘기 위한 여지도 있다고 생각한다. 앞으로 몇 년 동안 많은 새로운 응용프로그램들이 서버 기반 응용프로그램으로 작성될 필요가 있다. 새로운 리스프가 펄처럼 훌륭한 문자열 라이브러리를 갖추지 말라는 법이 없다. 그리고 이 새로운 리스프가 서버 기반 응용프로그램을 위한 강력한 라이브러리도 갖춘다면 큰 인기를 얻을 수 있을 것이다. 실제 해커들은 몇 개의 라이브러리 호출로써 어려운 문제를 해결할 수 있게 해 주는 새로운 도구 앞에서 콧대를 높이지는 않을 것이다. 기억하라. 해커들은 게으르다. 핵심 언어 부분에서 서버 기반 응용프로그램을 지원한다면 더 큰 승리를 얻을 수 있을 것이다. 예를 들어, 다중 사용자 프로그램을 명시적으로 지원하거나, 자료형 표식(type tag) 수준에서 데이터의 소유권을 구분하는 것이다. 서버 기반 응용프로그램들은 이 새로운 리스프가 무엇을 해킹하는 데 쓰일 것인지에 대한 해답도 제시한다. 리스프를 유닉스의 스크립트 언어로서 더 좋게 만드는 것도 나쁘지 않을 것이다. (더 나쁘게 만드는 것이 어려울 것이다.) 하지만 기존의 언어들을 뛰어넘기가 더 쉬운 영역이 있다고 생각한다. Tcl의 모형을 따라서 리스프를 서버 기반 응용프로그램을 지원하는 완벽한 시스템과 함게 제공하는 것도 좋을 것이라고 생각한다. 리스프는 서버 기반 응용프로그램에 적합하게 타고났다. 사용자 환경(UI)이 일련의 웹 페이지들뿐일 경우, 사전 닫힌 함수(lexical closure) ''역자 주: 함수가 (호출된 순간이 아니라) 정의된 순간의 변수를 기준으로 실행되는 함수''를 통해 서브루틴의 효과를 낼 수 있다. S식(s-expression)은 HTML에 멋지게 대응되고, 매크로는 HTML을 생성하기에 좋다. 서버 기반 응용프로그램을 작성하기 위해 더 좋은 도구가 필요하며, 새로운 리스프가 있어야 할 필요가 있다. 이 두 가지가 함께 한다면 더욱 효과적일 것이다. == 꿈의 언어 == 요약하는 셈치고 해커의 꿈의 언어를 묘사해 보도록 하자. 그 꿈의 언어는 아름답고 깔끔하고 간결하다. 빠르게 시작하는 대화형의(interactive) 상위 계층이 있다. 매우 적은 코드로도 흔한 문제들을 해결하는 프로그램을 만들 수 있다. 어느 프로그램에서든 프로그래머가 직접 작성한 거의 모든 코드는 그 응용프로그램에 특유한 코드이다. 나머지는 모두 알아서 만들어진다. 이 언어의 문법은 간결해서 실수가 적다. 불필요한 문자를 타자하거나, 쉬프트 키를 많이 사용할 필요도 없다. 추상화(abstraction)를 적극 활용하여 프로그램의 처음 판을 매우 신속하게 만들 수 있다. 그 후에, 최적화를 원할 때에는, 어디에 주의를 집중해야 할지 알려주는 정말 좋은 성능 분석 도구(profiler)가 있다. 필요하다면 인라인 바이트 코드도 작성하여, 내부 반복문을 어지러울 정도로 빠르게 만들 수 있다. 배울 수 있는 많은 좋은 예제들이 있으며, 이 언어는 아주 직관적이어서 2, 3분 만에 예제들을 통해 사용법을 배울 수 있다. 매뉴얼을 열심히 들여다 볼 필요가 없다. 매뉴얼은 얇고, 주의 사항이나 자격 조건도 거의 없다. 이 언어는 작은 핵심 부분과 강력하고 매우 상호 독립적인(orthogonal) 라이브러리들이 있다. 그 라이브러리는 핵심 언어 부분처럼 주의 깊게 설계되었다. 이 라이브러리들은 함께 잘 작동한다. 이 언어의 모든 것들은 좋은 카메라의 부품이 그렇듯이 서로 잘 어울린다. 아무것도 비추천(deprecated)되거나 호환성 때문에 남겨둔 것이 없다. 모든 라이브러리의 소스 코드는 언제든 손에 넣을 수 있다. 운영체제나 다른 언어로 만든 응용프로그램에 접근하는 것도 쉽다. 이 언어는 계층적으로 만들어진다. 상위의 추상화된 계층은 하위의 추상화된 계층을 기반으로 매우 명료한 방식으로 만들어지며, 원하면 얼마든지 그것을 파악할 수 있다. 절대적으로 숨겨야 하는 것이 아니라면 아무것도 숨기지 않는다. 이 언어는 추상화되어 있는데, 그것은 무엇을 지시하기 위해서가 아니라 일을 덜어 주기 위해서이다. 실제로 이 언어는 그 설계에 누구든 동등한 자격으로 참여하도록 격려한다. 그것의 모든 것, 심지어는 문법까지도 바꿀 수 있으며, 자기가 작성한 모든 것은 이미 정의되어 있는 것과 최대한 같은 지위를 갖는다. ---- CategoryDevelopment