“JavaScript는 사실상 Scheme”이라는 통념을 역사적·심리적 배경과 함께 비판적으로 검토한다. Scheme의 핵심 특성을 열거해 JS와 비교함으로써, 클로저 같은 일부 공통점만으로 두 언어를 동일시하는 것은 생각을 멈추게 하는 상투구일 뿐이며 JS 자체의 장점과 개성을 보지 못하게 만든다는 점을 논증한다.
요즘은 레딧에 들어가서 다섯 분도 지나지 않으면 누군가가 “JS는 스킴이지” 카드를 꺼내 든다. “JavaScript에는 Scheme과 공통점이 많다” 같은 무난한 말부터, 아예 “JavaScript는 기본적으로 Scheme다”라는 주장까지. 이건 기본적으로 미친 소리다. 적어도 미친 소리와 공통점이 아주 많다.
그게 미친 소리라는 걸 설득하기 전에, 잠깐 물러서서 왜 JS 신봉자들이 처음부터 그런 말을 하는지부터 생각해 보자. “그래, FORTRAN은 기본적으로 Icon이지”라거나 “Sather는 아주 탄탄한 SNOBOL 코어를 가지고 있어” 같은 말은 안 하잖나? 왜 이런 임의의 짝짓기가 나왔을까? 치밀한 과학적 연구 끝에, 두 가지 역사적 이유와 하나의 이상한 심리적 이유를 발견했다.
웹의 태고적 안개 자욱한 시절, “공사 중” 배너가 사방에 나부끼고 야생의 <font> 태그가 들판을 누비던 때, 브렌던 아이크라는 위대한 프로그래머가 있었다. 지금도 위대한 프로그래머 브렌던 아이크가 있지만, 그때도 있었다.
그는 소용돌이치는 연기와 함께 넷스케이프의 사무실에 나타나 브라우저에 Scheme을 가져오라는 도덕적 사명을 지니고 있었다. 안타깝게도, 양복 입은 사람들은 (늘 그렇듯 더 높은 목적을) 제대로 못하게 만들었다. 그래서 그가 열흘의 열병 같은 기간 동안 급히 짜 맞춰 만든 것은 JavaScript였다. 자바처럼 보이지만 자바와는 전혀 다르게 동작하는 언어였다.
자바의 의미론이 없다면, 도대체 어떤 의미론이 있었을까? 후대의 역사가들은 그 빈칸을 채우려 했다. Scheme이 아이크의 원래 절친이었으니, JS의 의미론도 거기서 왔다고 추정했다. 가설은 이랬다. 아이크는 상사를 달래기 위해 자신의 창조물에 세미콜론과 중괄호라는 양가죽을 씌웠을 뿐이고, 그 섹시한 늑대는 처음부터 속에 있었다는 것이다.
물론 이건 완전히 틀렸다. 그 양가죽 속 동물은 Self이지 Scheme이 아니다. (게다가 단일 부모 위임만 있는, 값싼 짝퉁 버전이다.) 하지만 세상에 Self를 기억하는 사람이 얼마나 있겠나? 그래서 신화 1번은 이렇다. 아이크는 처음엔 Scheme을 만들려고 했으니, JavaScript에는 여전히 깊은 Scheme의 뿌리가 숨어 있을 거라는 믿음이다.
하지만 그 신화가 생긴 건 훨씬 후의 일이다. 그전에 재미있는 일이 있었다. 어느 날, 넷스케이프는 전대미문의 숙취에서 깨어나 보니 웹에 스크립트 언어를 쑤셔 넣어 놨고, 수백만 명이 그걸 쓰고 있었다. 그런데 그 누구도 좋아하지 않았다. 단 한 명도.
그건 그저 640x480 해상도의 “Netscape 3.0에 최적화”된 지오시티즈 페이지에서 멋진 롤오버 애니메이션을 어떻게든 “대충 돌아가게” 만들려면 억지로 다뤄야 하는 이상한 무언가였다. 드롭다운 메뉴가 스스로 애니메이션을 하진 않으니까.
그 즈음, 더글라스 크락포드라는 괴짜가 나타났다. 그 시절의 10대 아마추어급 웹 디자이너들(이 글의 초라한 저자 포함)과 달리, 그는 진짜배기 컴퓨터 고수였다. 우리가 드림위버와 메모장을 쓰던 동안, 그는 아마 emacs, 아니면 ed, 혹은 누가 알겠나, troff를 썼을 것이다. 그는 비디오, 게임, 그리고 비디오게임 분야에서 일했다. 너드로서의 혈통을 굳히기라도 하듯, 그는 정통파 언어 덕후였다.
어찌어찌, 아마 술과 강력한 약, 그리고 연이은 내기 패배가 얽힌 끝에, 그는 그 화려한 출발에서 굴러 JS 코딩을 하게 되었다. 그 시절 JS를 쓰던 거의 모든 사람과 달리, 그는 더 나은 언어들을 알고 있었다. Scheme, Smalltalk(아마도), 심지어 E. (약이 아니라 언어 말이다. 물론 어느 쪽이든 그와 무관하다고 장담하진 못하겠다.)
보통 Scheme이나 Smalltalk에 손을 대면, 다른 언어 앞에서 저절로 콧방귀와 비웃음을 터뜨리는 불치병에 걸린다. 그런데 크락포드는 그 감염을 어떻게든 떨쳐 내고 JavaScript를 해부해 그 중심의 심연을 뚫어지게 보았다. 그가 보았다고 주장한 것은 함수형 언어였다. 정확히 말하면 Scheme.
그는 영적 여행에서 돌아와 복음을 새겨 넣고 성서에서 설교하기 시작했다. 그리고 이렇게, 한 번만이 아니라 여러 번에 걸쳐, 누구에게나 말했다.
JavaScript의 C 같은 문법, 중괄호와 투박한 for 문을 포함한 그 겉모습은 JS가 평범한 절차적 언어처럼 보이게 합니다. 하지만 이는 오해의 소지가 큽니다. JavaScript는 C나 Java보다 Lisp나 Scheme 같은 함수형 언어와 더 많은 공통점을 갖고 있기 때문입니다.
크락포드에겐 남다른 설득력이 있다. 그의 이력이 진짜로 인상적이기 때문이기도 하다. 그는 과거에도, 지금도 많은 훌륭한 일을 하고 있다. 그는 비유적으로도 문자 그대로도 백발의 현자이면서 최첨단에 서 있다. 게다가 통찰과 까칠하지만 미워할 수 없는 잔소리꾼 기질이 반반 섞인 화법을 가졌다. 한마디로, 그는 당신의 아버지 같고, 아버지가 말할 때는 얌전히 듣는 법이다.
곧, 새로운 세대의 프로그래머들이 이상한 입장에 놓였다. 많은 이들이 웹이 막 시작되던 때 어린 나이에 우연히 프로그래밍을 접했다. 그들의 첫 언어는 컴퓨터에 이미 깔려 있던 바로 그 언어, JavaScript였다. 어릴 적 장난감처럼 시작했는데, 몇 년 뒤 직업적으로 쓰게 되었다. 아무도 그 언어를 진지하게 보지 않는데도 말이다.
당신이 그들의 입장이라고 상상해 보라(이미 그럴 수도 있다). 건설 현장에서 팔뚝에 털 난 거구들이 망치를 휘두르는 바람에 팔털이 휘날리는 가운데, 당신은 어릴 적부터 갖고 다니던 침바른 헤진 담요로 못을 밀어 넣고 있다. 창피하다. 담요가 어떻게든 못을 박긴 하지만 말이다.
자신감이 떨어지고, 좀 힘없게 느껴진다. 메슈가 공연장에 찾아온 저스틴 비버 팬처럼, 지금 당신에게 정말 필요한 건 길거리 평판이다.
어딘가 유기적인 과정을 거쳐, 프로그래밍 언어의 판테온에는 위신 서열이 생겼다. 음악과 패션만큼이나 제멋대로지만 부인하기 어렵다. 한쪽 끝에는 라디오헤드, 반대쪽 끝에는 니켈백. 어떻게 그 자리에 섰는지는 아무도 정확히 모르지만, 어쨌든 거기에 있다.
라디오헤드 쪽에는 커먼 리스프, Scheme, Smalltalk 같은 것들이 있다. Scheme은 리스프보다 더 리스프 같아서, 라디오헤드가 늘 최신 앨범의 영감으로 꼽는 그 누구도 모르는 전위적인 밴드 같다. 만약 Lisp이 라디오헤드라면, Scheme은 크라프트베르크다.
JavaScript를 쓰면서 얼굴이 화끈거렸던 사람들에게 크락포드는 답을 주었다. JS는 대중 라디오 락 밴드가 아니었다. 날카롭고, obscure했다. Scheme이었다.
그뿐만 아니라, 그것은 ‘비밀리에’ Scheme이었다. 그러니 JS에 심취해 있다면, 당신은 가장 멋진 언어 중 하나를 쓰는 것일 뿐 아니라, 그것이 얼마나 멋진지 아는 선택받은 소수이기도 했다. 당신이 콜드플레이를 듣고 있더라도, 그건 브라이언 이노가 프로듀싱했기 때문일 뿐이다.
이 “JS = Scheme” 밈은, 아마도 바위와 나뭇가지를 주워 자기 손으로 컴퓨터를 만든 다음 자기 메모리를 직접 할당하는, 거친 C 프로그래머들 앞에서 주눅 든 프로그래머 무리에게 엄청난 정당성을 제공해 주었다.
내가 약간 과장했을지도 모른다. 아주 조금. 하지만 대충 그렇게 여기까지 왔다고 본다. 많은 프로그래머들이 JavaScript는 “기본적으로” Scheme이라고 믿는다. 자신들이 믿고 싶은 걸 주기 때문이다. 자신이 선택한 언어가 어느 정도의 위신이 있으며, 더 이상 부끄러워하지 않아도 된다는 믿음. 그리고 솔직히, 사실인지 아닌지 가를 만큼 Scheme을 제대로 아는 사람은 거의 없다.
글쎄, 나는, 프로그래밍 언어에 대한 백과사전 같은 지식과 SICP의 ‘내가 인정하기 민망할 정도는 아닌’ 닳은 사본을 들고, 안다. 이 신화를 지금 당장 잠재우자. 다음은 Scheme을 정의하는 특징들, Scheme을 특별하게 만드는 그 겔슈탈트다:
이 목록의 몇몇 항목은 논쟁의 여지가 있겠지만, 꽤 탄탄하다고 본다. 이제, JavaScript가 “기본적으로” Scheme이라면, 이와 꽤 근접해야 한다. 이 목록 중 JS가 가진 것은 다음과 같다.
JS에 렉시컬 스코프가 있다고는 하지 말라. JavaScript의 스코핑은 신 앞에서조차 혐오스러운 물건이다. 가이 스틸은 아직 살아 있는데, JS의 스코프는 그를 미리 그의 아직 비어 있는 무덤에서 뒤집히게 만든다. 마찬가지로, 문자열을 eval할 수 있다는 이유만으로 JS가 호모아이코닉하다고 주장하는 것도 터무니없다. 그게 호모아이코닉성의 기준이라면 C도 해당된다. 바이트 배열을 코드로 취급해 점프할 수 있으니까.
공정하게 말해, 공통점이 ‘좀’ 있긴 하다. 그러니 비교가 완전히 부당하다고만 할 수는 없지 않나? 아마 진짜 가늠하는 방법은 Scheme을 다른 언어들과 비교해 보는 것이다. 모두가 집요하게 붙드는 큰 특징은 클로저다. 어쩌면 클로저만 있으면 기본적으로 Scheme일지도 모른다.
그게 사실이라면, C#, Lua, D, Erlang, Haskell, PHP, Scala, Go, Objective-C, Python, Ruby, Smalltalk도 기본적으로 Scheme다. 다시 말해, 그 기준으로 JavaScript가 Scheme이라면, 모든 언어가 Scheme이고, 따라서 그 어떤 것도 Scheme이 아니다.
바로 그래서 “JS = Scheme” 밈이 나를 미치게 만든다. 우리를 더 멍청하게 만들기 때문이다. 이것은 생각을 멈추게 하는 상투구다. 정보량이 마이너스고, 사람들로 하여금 이전보다 언어에 대해 실제로 덜 알게 만든다.
만약 당신이 JavaScript가 가장 Scheme에 가까운 언어들 중 하나라고 생각한다면, Forth는 ‘진짜로’ 미니멀하고, Dart는 스코핑이 훌륭하고, Lua는 꼬리 호출 제거를 지원하고, Haskell과 Ruby에는 컨티뉴에이션이 있으며, C#에는 동적 타입이 있고, Io는 호모아이코닉하며, Go에는 클로저가 있고, Scala에는 매크로가 있으며, Clojure는 변이를 심각하게 싫어한다는 사실을 놓치고 있는 것이다.
동시에, JavaScript를 Scheme이 아니게 만드는 요소들도 무시하게 된다. JS는 훨씬 더 풍부한 문법을 갖고 있고, 데이터 표기에도 ‘아주’ 좋은 표기법이 있다. 나는 (이젠) 프로토타입의 큰 팬은 아니지만, Scheme에는 없는 흥미로운 디스패치 모델이기도 하다.
JavaScript를 Scheme에 갖다 붙이는 건 Scheme에 대한 누만이 아니라, JavaScript에 대한 누도 된다. 당신이 JavaScript의 팬보이라면(팬걸? 팬퍼슨?), 좋다. 하지만 ‘Scheme 대리인’의 팬보이가 아니라 ‘JavaScript’의 팬보이가 되라. “기본적으로 Scheme”이라고 말하는 건, 결국 JS를 부끄러워한다는 뜻을 다른 말로 하는 것뿐이다.
JavaScript가 부끄럽다면, 쓰지 마라. (요즘은 선택지가 아주 많다.) 그리고 정말로 좋아한다면, JS가 ‘있는 그대로’의 모습 때문에 좋아하라. 무작위 다른 언어와 공통으로 갖고 있는 그 작은 부분 때문이 아니라.