리치 히키와의 인터뷰 (마이클 포거스)

서문

이 글은 마이클 포거스가 클로저(Clojure)의 창시자인 리치 히키(Rich Hickey)를 인터뷰하여 CodeQuarterly에 게재한 글을 번역한 글입니다. 인터뷰가 게재된 잡지가 발행된 시기는 2011년 6월 경으로 추정됩니다. 이 글을 작성하는 목적은 두 가지입니다.

  1. 보존 CodeQuarterly 사이트와 함께 인터뷰의 일차 출처가 사라졌기 때문에 보존을 위해 사본을 남깁니다.

  2. 한국어 번역
    참 좋은 글인데 한국어 번역본이 없는 것 같아서 공유하고자 번역합니다.

리치 히키와 마이클 포거스가 진행하는 Q&A

리치 히키는 지난 20년 동안 소프트웨어 개발자이자 컨설턴트로 활동해왔으며 클로저 언어의 창시자로 가장 잘 알려져 있습니다. 클로저는 자바 가상 머신(JVM)에서 동작하는 리습(Lisp) 언어로 리습 계열 언어 중 스킴(Scheme)과 커먼 리습(Common Lisp) 이래로 최초로 광범위한 관심을 받은 언어입니다.

리치 히키는 클로저를 만들기 전에도 jfli, Foil, Lisplets, DotLisp 등 네 번에 걸쳐 리습을 자바나 마이크로소프트의 공통 언어 런타임(Common Language Runtime)과 합치려고 시도했지만 대중의 주목을 받은 것은 클로저가 처음이었습니다. 인터뷰 진행자인 마이클 포거스가 쓴 “클로저 프로그래밍의 즐거움”을 비롯해 지금까지 클로저에 대해 총 4권의 책이 출간되었습니다. 최초의 클로저 컨퍼런스인 ClojureConj는 2010년에 개최되었으며 약 200여 명이 참여했습니다. 이 인터뷰를 작성하는 시점에 추산하기에는 2007년에 개설된 클로저 구글 그룹에서 지금까지 4,880 명이 46,000 개 이상의 메시지를 작성했습니다.

리치 히키는 작곡을 전공했고, 기타리스트로 활동했으며, C++ 전문 프로그래머로써 뉴욕 대학교에서 고급 C++ 강의를 가르치기도 했습니다. 마이클 포거스는 이 인터뷰에서 리치 히키와 복잡성(complexity), 추상화(abstraction), 그리고 클로저의 과거, 현재, 미래에 대해서 이야기합니다.

포거스: 프로그래밍을 시작하게 된 계기가 무엇이었나요?

히키: 녹음실을 운영할 당시에 컴퓨터로 할 수 있는 것들에 흥미를 느껴서 컴퓨터를 한 대 구입했습니다. 당시는 MIDI가 나온지 얼마 안 된 시기여서 컴퓨터를 활용해서 할 수 있는 새로운 것들이 가득했습니다. 그래서 C와 어셈블리를 독학한 뒤 음악 소프트웨어를 작성하기 시작했고, 그러다가 바로 푹 빠져버렸습니다.

포거스: 기타를 치는 것으로 알고 있는데 맞나요?

히키: 네. 대학 때 작곡을 전공했습니다.

포거스: 뛰어난 프로그래머가 뛰어난 음악가이기도 한 경우를 종종 보았습니다. 음악이 프로그래밍과 관련이 있다고 보나요?

히키: 음악에서 유용한 능력과 프로그래밍에서 유용한 능력은 상대 분야에서도 종종 유용하다고 생각합니다. 코딩과 연주는 연습할수록 실력이 늘어난다는 점을 제외하면 매우 다르다고 생각하지만, 소프트웨어 설계와 작곡은 서로 닮은 점이 많다고 봅니다. 둘 다 추상적 개념을 다루고 구성하여 특정한 시간적 구간 상에 이를 구현시키는 방법을 마음 속에 그려보는 형태를 가집니다. 프로그램의 경우 프로세스로 구현하겠죠. 소프트웨어 설계는 제가 작곡을 통해서 추구하려 했던 창조적 욕구를 충족시킬 수 있었고, 이윽고 완전히 대체하게 되었습니다.

포거스: 최초로 작성했던 흥미로운 프로그램은 무엇이었나요?

히키: 제가 초창기에 작성했던 간단한 진화 관련 프로그램이 있는데, 이를 작성하며 컴퓨터 연산을 통해서 할 수 있는 것들에 대해 흥미를 많이 가지게 되었습니다. 벌레들이 음식을 찾아서 화면 상에서 움직이는 프로그램이었는데 최초 움직임은 무작위로 결정되었습니다. 자러 가기 전에 벌레들이 화면에서 돌아다니도록 프로그램을 실행한 뒤에 일어나면 벌레들이 진화해서 자연스럽고 효과적인 이동 전략을 사용하는 것을 볼 수 있었죠. 그 때 저는 시뮬레이션과 자동 생성 프로그램(generative programming)을 활용하면 분석과 계산을 통해서는 도달할 수 없는 것들을 찾아내고 발견할 수 있다는 것을 깨달았습니다.

포거스: 프로그래머로서의 능력을 어떻게 발전시키나요? 자주 하는 연습이나 연습용 프로젝트가 있나요? 히키: 끊임 없이 독서를 합니다. 저는 컴퓨터가 유용한 일을 하도록 시키는 프로그램만 작성하고, 따라서 연습을 위한 프로그래밍을 따로 하지는 않습니다. 문제에 대한 해법을 입력하는 시간보다는 문제에 대해서 생각하는 시간을 더 길게 가지려 노력합니다.

포거스: 독서에 대한 언급이 나왔는데, 예전에 아마존에 만들었던 클로저 책장이 매우 인기있었죠. 거기 나열한 책들 중에서 모든 프로그래머가 반드시 읽어야 한다고 생각하는 책이 있나요?

히키: 그 중 몇 권만 집어서 말하지는 못하겠습니다. 각 책마다 집중해서 다루는 내용과 등한시하는 내용은 서로 다릅니다. 다른 사람들에게 무엇인가를 꼭 해야만 한다고 추천하는 것은 조금 부담스럽네요. 개인적으로는 언급된 목록에 있는 것과 유사한 책이나 온라인 상에 공개되어 있는 학계 논문을 읽으려고 지속적으로 노력합니다. 그리고 저는 저와 함께 일하는 사람들이 배움에 매진하는 모습을 보이는 것을 좋아합니다.

포거스: 클로저 책장 목록에 등재하셨던 책들에 대해서 조금 이야기해보죠. 예를 들어 클로저는 겉보기에는 루비와 매우 다른데도 토머스, 파울러, 헌트가 저술한 프로그래밍 루비 1.9 책을 목록에 올려놓으셨었죠. 그 책이, 그리고 조금 더 전반적으로 루비가 클로저 디자인에 어떤 영향을 미쳤나요?

히키: 음, 영향은 긍정적일 수도 부정적일 수도 있습니다. 저는 파이썬과 루비를 보면서 새로운 문법을 또 하나 만들어 내거나, 새로운 객체 시스템을 또 하나 만들어 내고 싶지 않다는 마음을 확고히 가지게 되었습니다. 하지만 두 언어는 간결함에 대해 높은 기준점을 제시하기도 했습니다.

포거스: 알골(ALGOL) 계통의 문법을 루비나 파이썬이 했던 것 이상으로 간결하게 만들 수는 없을 것이라고 생각하십니까?

히키: 그건 모르겠습니다. 제가 더 흥미를 가지고 있는 주제는 간결함이 아니라 복잡성을 줄이는 것입니다.

포거스: 그러면 그 주제에 대해서 조금 이야기해봅시다. 언어와는 거의 무관한 문제 자체의 복잡성이 있고, 언어 때문에 발생하는 부수적인 복잡성이 있습니다. 클로저는 후자, 즉 부수적인 복잡성을 어떻게 완화시키나요?

히키: 부수적인 복잡성을 줄이는 것은 클로저의 주요 목표이며, 클로저가 언어의 각 부분에서 이를 어떻게 달성하고 있는지 확인해볼 수 있습니다. 예를 들어 변경 가능한 상태(mutable state)는 부수적 복잡성입니다. 변경 가능한 상태의 작동방식은 간단해 보이고, 최소한 익숙하게 느껴지기는 하지만 실제로는 매우 복잡합니다. 제 생각에 이는 시스템에서 가장 심각한 문제입니다. 그래서 클로저에서는 기본 설정으로 불변성 데이터를 사용합니다.

마침 문법에 대해서 이야기하고 있으니 고전적인 리습을 조금 살펴봅시다. 리습 문법은 모든 것이 괄호로 감싸여진 심볼, 숫자, 그리고 그 외 몇 가지 요소의 리스트로 이루어진, 일견 가장 간단한 문법입니다. 이보다 간단한 문법이 있을까요? 하지만 실제로는 간단한 문법이 아닙니다. 그런 통일성을 유지하기 위해서는 리스트의 의미를 상당히 다양한 방식으로 활용할 필요가 있기 때문입니다. 같은 리스트라도 함수 호출일 수도 있고, 구조체를 모아놓은 것일 수도 있고, 데이터값일 수도 있습니다. 그리고 이를 판단하기 위해서는 문맥을 활용해야만 하며, 이는 코드를 살펴보고 의미를 파악하려고 할 때 받는 인지적 부하를 증가시킵니다. 클로저는 리스트 외에도 몇 가지 복합적 데이터값을 추가하여 문법에 포함시켜 사용합니다. 그럼으로써 리스트는 거의 항상 함수 호출같은 것들을, 벡터는 데이터값을 모아둔 것들을, 그리고 맵은 자체적인 값을 가진다는 것을 표현할 수 있게 되었습니다. 세 가지 데이터 구조를 사용함으로써 단일 데이터 구조를 사용할 때보다 인지적 부하를 상당히 줄일 수 있습니다.

우리는 프로그래머로서 다양한 종류의 부수적 복잡성에 상당히 익숙해졌지만, 그렇다고 문제가 덜 복잡해지는 것은 아니죠. 그저 우리가 복잡성을 보다 능숙하게 처리할 수 있게 되었을 뿐입니다. 하지만 그러기보다는 문제의 본질을 해결하려고 하는 편이 더 유용하지 않을까요?

포거스: 클로저가 부수적 복잡성은 그렇게 해소할 수 있다면, 실제 문제를 해결하는 것은 어떻게 도와줄 수 있나요? 예를 들어 이상적인 객체 지향 패러다임의 목적은 코드 재사용을 용이하게 하는 것인데, 고전적인 객체 지향 언어가 아닌 클로저에서는 재사용을 쉽게 하기 위해서 코드를 어떻게 구성할 수 있나요?

히키: 객체 지향과 재사용에 대해서는 할 말이 좀 있습니다만, 일단 재사용을 함으로써 문제를 보다 간단하게 해결할 수 있게 되는 것은 사실입니다. 차를 만들기 전에 바퀴부터 다시 발명할 필요가 없어지니까요. 클로저는 JVM에서 돌아가기 때문에 다양한 라이브러리를 가져와 사용할 수 있습니다. 하지만 그렇다면 재사용할 수 있는 라이브러리는 어떤 특징을 가지고 있어야 할까요? 먼저 한두가지 종류의 기능을 잘 수행해야 하고, 외부 의존성이 적어야 하고, 클라이언트 코드에 요구하는 사항이 적어야 합니다. 이런 특성은 객체 지향에 어긋나는 것이 아니며, 전부는 아니지만 상당수의 자바 라이브러리가 이 기준을 충족하고 있지요.

하지만 저는 알고리즘 수준까지 내려가면 객체 지향이 재사용성을 심각하게 저해한다고 생각합니다. 특히 단순한 정보를 담은 데이터를 표현하기 위해서 객체를 사용하는 것은 거의 범죄에 준할 정도로 심각한 문제라고 보는데, 이는 관계대수(relational algebra)와 같이 보다 강력하고 선언적이고 범용적인 방식을 사용하는 대신, 오히려 각 정보 하나하나에 대해서 마이크로 언어, 달리 말해 클래스 메서드를 생성하는 방식이기 때문입니다. 어떤 정보를 담기 위해 독자적인 인터페이스를 갖춘 클래스를 만들어내는 것은 단편소설을 쓸 때마다 새 언어를 만들어내는 것이나 마찬가지입니다. 이는 재사용성을 저해하고, 일반적인 객체 지향 어플리케이션에서 코드의 양이 폭발적으로 증가하는 결과를 초래합니다. 클로저는 이런 방식 대신 간단한 결합형 모델(associative model)을 사용해서 정보를 표현하는 것을 권장합니다. 그러면 다양한 타입의 정보에 공통적으로 재사용할 수 있는 알고리즘을 작성할 수 있습니다.

결합형 모델은 클로저에서 제공하는 여러가지 추상적 개념들(abstractions) 중 하나에 불과하며, 이 추상적 개념들이야말로 클로저가 재사용성을 위해 사용하는 방법인 “추상적 개념에 작용하는 함수”의 기반입니다. 적은 수의 확장 가능한 추상적 개념들을 원소로 가지는 열린집합과, 이에 작용하는 다수의 함수들을 원소로 가지는 열린집합을 사용하는 것이야말로 알고리즘 재사용성과 라이브러리 상호운용성의 핵심이라고 생각합니다. 대부분의 클로저 함수는 방금 언급한 추상적 개념들에 대하여 정의되어 있고, 라이브러리 작성자들도 라이브러리의 입력형태와 출력형태를 이런 추상적 개념들에 대하여 설계합니다. 덕분에 서로 독립적으로 개발된 라이브러리들 사이에서도 매우 우수한 상호운용성을 달성할 수 있었습니다. 이는 객체 지향에서 볼 수 있는 DOM 같은 것들과 명백하게 대비됩니다. 물론 객체 지향에서도 인터페이스 등을 사용해서 비슷한 방식으로 추상화를 할 수 있기는 합니다. java.util 콜렉션이 그 예시입니다. 하지만 그게 불가능한 경우도 그만큼 많습니다. java.io 등이 그렇죠.

포거스: “간단한 결합형 모델을 사용해서 정보를 표현한다”는 말이 무슨 의미인지 설명해주실 수 있나요?

히키: 정보를 표현하기 위해 사용되는 클래스는 명명된 속성(properties/attributes)을 값과 짝지어 놓은 맞춤형 결합형 맵(associative map)인 경우가 대부분입니다. 하지만 맵을 커스토마이즈하는 과정을 거치고 나면 그 결과물은 더 이상 범용적인 맵으로 취급할 수 없게 되는데, 그러면 정보를 범용적으로 다룰 수 있는 코드를 작성하는 것이 불가능해집니다. 왜냐하면 그런 코드를 작성하기 위해서는 데이터의 속성을 이름이나 키를 사용해서 범용적으로 접근하고 변경하고 추가하거나, 열거(enumerate)할 수 있어야 하기 때문입니다. 결합형 정보 모델은 그런 범용적 능력을 강조하고, 이를 유지합니다.

포거스: 혹시 이런 추상화에 기반한 접근법이 적합하지 않은 분야가 있습니까?

히키: 저는 넓게 보았을 때, 이 접근법이 보편적인 매력을 지니고 있다고 봅니다. 성능 개선을 추구할 때에는 추상화나 클로저 같은 동적 언어가 부담스럽게 느껴질 수도 있습니다. 극한의 성능을 추구하는 사람들은 클로저가 목적에 적합하지 않다고 생각할 수도 있지요. 그런 사람들은 자바도 스택과 배열에서 복합데이터타입(composite data type)을 쓸 수 없기 때문에 적합하지 않다고 판단할 수도 있습니다.

그렇긴 하지만 이는 클로저에서 지속적으로 개선하고 있는 부분이기도 합니다. 클로저는 사실 동적 언어로서는 이미 상당히 빠른 편입니다. 타입 힌트를 사용하면 자바만큼이나 빠르게 로컬 코드를 생성할 수 있고, 원시타입 인자 및 반환값에 관해 새로 추가된 기능을 통해 그 속도를 보다 넓은 영역에도 적용할 수 있게 되었습니다. 완전한 타입 시스템이 가지는 경직성과 복잡성을 발생시키지 않으면서도 이 기능을 가장 높은 추상화 단계까지 적용시킬 수 있을지는 아직 모르겠는데, 살펴보려고 합니다.

포거스: 과거에 저술한 “Callbacks in C++ Using Template Functors”라는 제목의 논문에서는 C++, 객체 지향 프로그래밍과 정적 타입을 긍정적으로 바라보았었습니다. 그 생각이 왜 바뀐 것입니까?

히키: 생각이 바뀌었다는 말이 맞는지는 모르겠습니다. 그 논문에서 쓴 내용은 C++는 유연한 언어이고, C++에 콜백 시스템을 구현할 때는 언어의 객체 지향성과 정적 타입에 맞추어서 구현해야 한다는 말이었습니다. 그 글을 다시 읽으면서 제가 더 흥미롭게 생각한 것은 제가 15년 전 그 때 했던 말, 즉 믹스인(mixin)이나 파생(derivation)을 코드 확장 메커니즘으로 사용해선 안 된다는 주장을 지금도 하고 있다는 것입니다.

그렇긴 하지만 당시에 저는 분명 C++광이었습니다. 그 후로 C++를 5년을 더 하고 나서야 거기서 벗어날 수 있었죠. C++의 복잡성은 기가 막힐 정도입니다. 제 생각에 C++는 GC가 없었기 때문에 라이브러리 언어라는 원래의 목표에 도달하지 못했고, 정적 타입은 거대한 객체 지향 시스템이 끔찍한 진흙덩어리가 되어버리는 것을 저지하지 못했습니다. 변경 가능한 거대한 객체 그래프(object graph)는 골칫덩어리고, const만으로는 이를 감당할 수 없습니다. 성능에서의 C++의 강점이 퇴색되거나 덜 중요해지자, 왜 굳이 힘들게 C++를 써야하나 의문이 들 수밖에 없었습니다. 요즘은 매우 특수한 경우를 제외하면 GC 없는 언어를 사용하는 모습이 그려지지 않습니다.

그러다가 커먼 리습을 알게 되었는데, 훨씬 더 유연하고, 동적이고, 간단하면서도 충분히 빨랐기에 이거야말로 내가 프로그램을 작성하고 싶은 방식이라고 결정했습니다. 그리고 최종적으로 클로저 덕분에 그런 프로그래밍 방식을 현실적으로 할 수 있게 되었습니다.

포거스: 이메일에서 리습을 배우는 과정에서 즐거움을 느꼈다고 적었주셨었죠. 참고로 제가 쓴 책 제목을 거기서 따왔습니다. 그게 구체적으로 어떤 느낌인지, 그리고 리습이 왜 그런 느낌을 줄 수 있는지 설명해주시죠.

히키: 리습은 개념적으로 간결하고, 많은 라이브러리를 갖추고 있고, 매크로를 커스토마이즈할 수 있습니다. 덕분에 정말 의미 있는 리습 코드만 작성할 수 있는 지점에 도달할 수가 있습니다. 그리고 그 지점에서는 바둑을 두거나 악기를 연주하거나 명상을 할 때와 비슷하게 몰입을 할 수 있습니다. 그럴 때는 몰입 상태에 동반되는 희열을 느낄 수 있습니다.

포거스: 업무적으로 무슨 프로그래밍 언어를 사용해 보았습니까?

히키: 주로 C, C++, 자바, C#, 커먼 리습, 클로저를 사용했습니다.

포거스: 두 번째로 좋아하는 언어는 무엇인가요?

히키: 그 언어들 중에서 충분히 만족스러운 언어가 있었다면 클로저를 만들지는 않았겠죠. 클로저가 아닌 다른 언어를 사용해야만 한다면 잘 작성된 커먼 리습과 그 소스 코드가 가장 좋을 것 같습니다. 여유 시간이 조금 더 있다면 하스켈을 쓰고 싶습니다.

포거스: 사람들이 클로저에 열광하는 이유에 대한 개인적인 이론이 있습니다. 바로 폴 그레이엄(Paul Graham)이 리습에 대해서 쓴 수필에서 장려하는 전반적인 열린 사고방식, 그리고 파이썬과 루비의 인기에서 기인한 부분이 있다는 것입니다. 클로저가 지금까지 성공할 수 있었던 것은 무엇 덕분이라고 보십니까?

히키: 그 이론에 저도 동의합니다. 폴 그레이엄의 수필은 사람들이 리습, 프로그래밍을 보는 리습식 관점, 그리고 일반적 통념을 거부하는 것의 중요성에 관심을 가지도록 하는 등 매우 큰 영향을 미쳤다고 봅니다. 그리고 파이썬과 루비, PHP, 자바스크립트는 자바, C#, C++ 외의 다른 언어로도 성공하는 모습을 명백히 보여줌으로써 언어적 다양성의 부흥기가 도래하는 것에 기여했다고 봅니다. 클로저가 성공할 수 있었던 배경에는 이런 모든 것이 있었습니다.

재미있는 점은 클로저가 제공하는 기능 중 다른 언어에서 찾아볼 수 없는 특별한 것은 거의 없다는 것입니다. 하지만 클로저는 언어 기능 및 능력을 각각의 축으로 표현한 다차원적 공간 안에서 자신만의 자리를 잡고 있다고 생각합니다. 그렇지 않았다면 제가 애초에 만들지 않았겠죠. 그 자리야말로 제가 프로그램을 하고 싶은 지점이고, 그 지점을 마음에 들어하는 다른 사람들도 충분히 많이 있다고 생각합니다.

포거스: 클로저 커뮤니티에 지금의 분위기를 정착시키기 위해서 개인적으로 많은 노력을 해왔는데, 언어의 커뮤니티가 그 언어의 성공에 얼마나 기여한다고 봅니까?

히키: 정말 큰 요소라고 봅니다. 저는 클로저 커뮤니티에 매우 만족하고 자랑스럽게 여깁니다. 클로저 커뮤니티원들은 서로 도우려 하고, 공손하고, 긍정적입니다. 제 생각에 핵심적인 요소는 커뮤니티원들이 커뮤니티 자체를 소중히 여기는 것인데, 그래야 커뮤니티원들이 감정을 토해내거나 자신이 옳다고 입증하려 하기보다는 커뮤니티의 전체적인 질을 유지하는 것을 더 중요하게 여기기 때문입니다.

포거스: 클로저를 만들 때까지 진행했던 리습 관련 프로젝트에 대해서 간략하게 이야기해볼까요? 구체적으로 dotLisp, Foil, Lisplets의 목표는 무엇이었습니까?

히키: dotLisp는 누구나 한 번은 겪게 되는 “리습 인터프리터 직접 만들어보기” 프로젝트였습니다. 유일하게 흥미로운 부분이라면 클로저처럼 호스트 시스템 상에서 돌아가고 호스트 시스템에 편리하게 접근할 수 있도록 해주었다는 것입니다. 이 때 호스트는 CLR이었죠.

Jfli는 그 다음에 진행한 프로젝트였는데, 커먼 리습 프로세스 안에 JVM을 붙여서 자바에 접근할 수 있도록 시도해본 경우였습니다. 잘 돌아가기는 했는데 여전히 물과 기름처럼 유리된 느낌을 주어서 만족스럽지는 않았습니다. Foil은 프로세스 밖에서 동작하는 것을 제외하면 사실상 동일한 개념이었습니다. 자바와 CLR 상호운용성을 지원하기 위해 동일한 sexpr 와이어 프로토콜을 사용했죠. 여전히 유리된 느낌이 있었고, 동일 프로세스에서 돌아가는 것보다 느렸지만 이론적으로는 더 잘 분리되어 있었습니다.

Lisplets는 더 확실히 분리된 구조였는데, 자바 서블릿 요청과 응답을 sexpr로 변환해서 서블릿을 리습으로 작성할 수 있도록 했습니다.

결과적으로 이 중에서 전통적인 소프트웨어 업체에 리습을 스리슬쩍 들여올 수 있도록 해주거나, 풍부한 자바 라이브러리를 리습에서 만족스러울 정도로 빠르게 사용할 수 있도록 해준 프로젝트는 없었습니다.

포거스: 이런 실험에서 얻은 교훈 중에서 클로저를 만들 때 도움이 된 것이 있었나요?

클로저: 먼저 전통적인 객체 지향 시스템에 접근할 수 있는 만족스러운 수준의 리습식 문법을 만들 수 있다는 것, 그리고 호스트와 GC를 공유하는 등 같은 울타리 안에 있는 편이 훨씬 좋다는 것 등이었습니다. FFI에서 외부(foreign) 부분은 없어져야 합니다.

포거스: 예전에는 JVM과 CLR에서 동시에 클로저를 개발했었는데, 왜 최종적으로 JVM에만 집중하기로 결정했나요?

히키: 똑같은 일을 두 번 하는 것에 질렸고, 대신 하나의 일을 두 배로 하고 싶었습니다.

포거스: 영향이 부정적인 측면을 가질 수도 있다고 앞서 말하신 바 있는데요, 클로저 책장에 이반 브라트코(Ivan Bratko)가 저술한 Prolog Programming for Artificial Intelligence를 포함시킨 것이 그런 경우에 해당하는지 궁금합니다. 프롤로그를 선언형 언어라고 보는 일반적인 관점이 과장되었다고 다른 곳에서 이야기하신 적이 있었죠. 프롤로그가 클로저에 부정적인 영향을 미쳤다고 이해해도 될까요?

히키: 과장되었다고 했던 것은 아니었습니다. cut/fail을 사용하거나 구문 순서에 의존하거나 하지 않았다면 선언형 특성이 더욱 뚜렸했을 것이라는 의미였습니다. 그럼에도 불구하고 프롤로그는 우리가 일상적으로 쓰는 언어보다는 훨씬 선언형 특성이 강하고, 선언형 방식으로 나아가는데 영감을 주는 언어입니다. 클로저 개발 초창기에 리습 기반 프롤로그를 사용해서 조건 기반 디스패치 시스템(predicate dispatch system)의 프로토타입을 만든 적이 있었습니다. 결국 그것을 클로저에 넣지는 않았지만 저는 조건 기반 디스패치, 그리고 클로저에 타입 시스템 대신 논리 시스템을 사용하는 것에는 여전히 관심을 가지고 있습니다. 그러니 아직 충분히 제대로 활용하지는 못했지만 분명히 긍정적인 영향을 주었다고 할 수 있겠습니다.

포거스: 클로저 데이터로그(Datalog) 구현체를 자세히 살펴보았는데, 사람들의 관심을 많이 받지 못하는 것 같아서 안타깝게 생각합니다. 데이터로그나 그 파생물이 방금 말한 “논리 시스템”의 기반으로 사용될 수 있을까요?

히키: 네, 당연합니다. 데이터로그는 저도 매우 좋아합니다.

포거스: 프로그래머가 실수를 하거나 안 좋은 코드를 작성하는 것을 방지하는데 프로그래밍 언어의 설계가 얼마나 큰 역할을 해야할까요?

히키: 이 주제에 대해서는 각 언어가 당연히 서로 다른 방식으로 접근할 수 있기 때문에 “어떻게 해야한다”고 말하는 것은 내키지 않는군요. 개인적으로는 사람들이 틀린 일을 하는 것을 방지하기보다는 옳은 일을 할 수 있도록 해주는데 집중하고 있습니다. 결국 사람들이 실수를 하거나 안 좋은 코드를 작성하는 것을 방지할 수 있는 방법은 없으니까요.

포거스: 그에 연관된 주제로, 클로저의 타입이 데이터를 감추는 캡슐화를 하지 않는다는 것을 놀랍게 여기는 사람들이 있습니다. 데이터를 감추지 않기로 결정하는 이유는 무엇입니까?

히키: 먼저 분명히 해야할 것은 클로저는 추상적 개념에 대한 프로그램을 작성하는 것을 매우 강조한다는 점입니다. 그래도 어느 시점에서는 데이터에 접근할 필요가 생기죠. 그런데 private 개념을 사용하려면 그에 상응하는 권한과 신뢰의 개념도 필요해집니다. 이는 가치는 거의 더해주지 않으면서도 복잡성은 엄청나게 증가시키고, 시스템을 경직시키고, 데이터를 어울리지 않는 자리에 놓도록 강제하곤 합니다. 그뿐만 아니라 단순한 정보를 클래스에 집어넣음으로써 발생하는 비용도 있죠. 데이터를 변경할 수 없다면 접근 권한을 제공해도 크게 문제가 될 것은 없습니다. 변할지도 모르는 데이터에 의존하는 사람이 있을 수도 있다는 것을 제외한다면요. 하지만 어차피 사람들은 실생활에서도 변할지도 모르는 것에 의존하고, 그게 변하면 그에 맞춰서 대응합니다. 상식적인 사람이라면 변할지도 모르는 것에 기반을 두고 판단을 내렸다면, 추후에 변화에 대응해야할 수도 있다는 것 또한 알고 있을 것입니다. 이는 결국 어떻게 리스크를 관리할지에 대한 판단이고, 프로그래머들이 자율적으로 할 수 있어야 한다고 생각합니다.

추상적 개념에 대해 프로그램을 작성하고 싶어하거나, 구체적인 구현체 내용을 결합시키는 것을 경계하는 등의 분별력도 없다면 어차피 절대 좋은 프로그래머가 되지 못할 것입니다.

포거스: 프로그래머의 분별력과 언어의 철학 사이에는 어떻게 선을 그어야 할까요? 불변성을 예로 들자면, 불변성을 언어 수준에서 강제하는 대신 프로그래머가 불변성 데이터를 사용하는 관습을 따라야한다고 하는 것으로 대체할 수 있을까요?

히키: 불변성 데이터를 사용하는 관습같은 것은 없습니다. 그런 관습을 관철시켜보려했던 사람이라면 누구나 이 말을 뒷받침해줄 것입니다. 가장 중요한 것은 데이터 구조가 오직 불변성 API만 제공하는가입니다. 그 외의 API도 제공한다면 그건 불변성 데이터가 아닌 것일 뿐입니다.

강제성은 독립적인 특성입니다. 이갠 강제성에 아무 가치도 없다는 의미는 아닙니다. 강제성이 있으면 이를 바탕으로 다양한 방식의 최적화를 할 수가 있으니까요. 하지만 세상에 공짜는 없습니다. 순수성을 강제할 수 있는 타입 시스템은 복잡합니다.

포거스: 클로저는 “진짜 리습”이 아니라고 하는 사람들에겐 어떤 말을 해주고 싶나요?

히키: 그런 사람들에게 내 시간을 쓰기에는 인생이 너무 짧습니다. 이미 다수의 리습 전문가들이 클로저를 리습이라고 인정했습니다. 모든 사람들이 각자 자신이 가장 좋아하는 리습보다 클로저를 더 좋아할 것이라고 기대하지도 않습니다. 클로저가 다른 리습과 다른 부분이 없었다면 애초에 존재할 이유도 없었겠죠.

포거스: 리습-1과 리습-2처럼 분명한 언어적 선택지를 제외한다면, 클로저는 커먼 리습이나 스킴(Scheme)과 어떻게 다르고, 어떻게 발전해나갈 생각입니까?

히키: 가장 의미있는 변경점은 두 가지입니다. 먼저 코어 라이브러리가 구체적인 데이터 타입이 아니라 추상적 개념에 대하여 구현되어 있다는 점입니다. 즉 콘(con)과 셀(cell) 대신 시퀀스(sequence)와 결합형 추상적 개념(associative abstractions) 등을 대상으로 구현되어 있습니다. 그리고 코어 데이터 구조가 불변성, 영속성(persistent)을 지닌다는 점입니다.

포거스: 아까 클로저를 사용해서 전통적인 소프트웨어 회사에 리습을 스리슬쩍 들여올 수 있다는 말을 하셨었는데, 이런 측면에서 다른 클로저와 다른 JVM 기반 리습이 어떻게 다릅니까

히키: 별로 다르지 않습니다. JVM 기반 언어는 모두 비슷한 방식으로 스리슬쩍 들여올 수 있죠.

포거스: 클로저가 이만큼이나 인기를 누리게 되어서 놀랐다고 말하신 적이 있는데, 그런 것 치고는 클로저의 최초 버전을 만들기 위해서 거의 수입도 없이 인생의 일이년을 걸지 않았나요?

히키: 클로저를 만들기 시작한 것은 제 스스로에게 준 안식년 도중이었습니다. 일에서의 휴식이 아니라, 완전히 자유로운 개인으로써 일하기 위한 휴식이었죠. 다른 사람들이 어떻게 생각할지, 어떻게 수익을 낼지에 대해 전혀 생각하지 않고 내가 옳다고 생각하는 것을 하기로 했었습니다. 클로저를 공개할 때는 보통 새 언어가 그러하듯이 열 명에서 많아봐야 백 명 정도가 쓸 것이라고, 운이 좋으면 누가 도와주거나 코드 기여를 할지도 모른다고 생각했습니다.

클로저는 급격히 인기를 얻었고, 따라서 최초에 계획했던 안식년보다 훨씬 많은 시간을 필요로 하게 되었습니다. 그렇기 때문에 제가 투자한 비용을 조금 만회하려하고 있습니다. 처음부터 수익을 목적으로 했다면 클로저가 탄생하지는 않았겠죠. 하지만 클로저에 투자한 것에 후회는 없습니다.

포거스: 클로저를 소개하는 영상을 여럿 공개했는데, 언어에 대한 활발한 관심을 불러모았죠. 특히 만들어진지 얼마 되지 않은 언어로써는 아주 훌륭한 마케팅 전략이었다고 생각합니다. 이는 마케팅 자료로 사용하기 위해서 일부러 만든 것인가요, 아니면 순수하게 정보를 제공하려고 노력하다가 생겨난 부산물인가요?

히키: jfli와 Foil 메일링 리스트에 등록되어 있던 극소수의 사람들에게 클로저의 존재에 대해 알리기 위해 보낸 최초의 이메일을 제외하면 클로저를 의도적으로 마케팅한 적은 없습니다.

연사로 초대를 받아서 발표를 많이 했는데, 영상은 그 중 일부를 녹화한 것입니다. 발표를 하는데 들인 노력을 활용하는 상식적인 방법이라고 생각했죠. 영상이 많은 관심을 받은 것에는 사실 꽤 놀랐는데, 매번 50명, 100명에게 발표하는 것보다 그런 영상이 훨씬 더 효율적이라는 것을 보여준다고 생각합니다.

포거스: 저는 하스켈은 관련 논문을 읽을 수 있을 정도로만 할 줄 아는데, 제가 보기에는 클로저는 하스켈의 영향을 많이 받은 것 같습니다. take, drop, iterate, repeat 등 핵심적인 함수의 이름과 작동 방법이나 프로토콜 기능 등 클로저에는 하스켈 프로그래머가 바로 알아볼만한 것들이 많이 있습니다. 클로저에 대한 하스켈의 긍정적, 부정적 영향에 대해서 이야기해주실 수 있습니까?

히키: 하스켈은 매우 훌륭하고 경외심을 불러일으키는 언어라고 생각합니다. 실무에서 써본 적은 없지만 클로저에 긍정적인 영향을 준 것은 분명합니다. 하스켈은 확실히 클로저보다 함수형 프로그래밍의 이상에 훨씬 충실한 언어입니다. 특히 다른 점은 타입을 통해서 강제성을 부여하는 방식입니다.

어떤 면에서 클로저는 정적 강제성이 없어도 함수형 프로그래밍의 장점을 얼마나 많이 제공할 수 있는지에 대한 실험이라고 볼 수도 있습니다. 클로저는 불변성 데이터와 순수 함수를 기본으로 제공하고 사용하게 하는 것만으로도 불변성 데이터와 순수 함수의 장점을 많이 누릴 수 있다는 것을 분명히 보여줍니다. 이는 난간을 설치해서 보도에서만 걷도록 강제하지 않더라도 보도에서 걷는 것의 장점을 많이 누릴 수 있는 것과 유사합니다.

저는 타입 시스템을 실용적으로 사용하려고 할 때 가장 큰 난관은 타입 시스템의 표현력을 증가시킬 때, 복잡성이 그에 상응하거나 더 빠른 속도로 증가하지 않도록 하는 것이라고 봅니다. 아직까지 이에 성공한 경우는 보지 못했고, 따라서 타입 시스템은 프로그래밍의 복잡성을 줄이려는 제 의도에 부합하지 않습니다.

프로토콜의 경우, 일반적인 객체 지향에서 사용하는 함수와 데이터를 결합하는 방식보다는 그 둘을 분리하는 방식이 보다 유연하고 확장성이 뛰어나다는 것을 보여준다는 점에서 하스켈의 타입클래스와 커먼 리습의 제네릭 함수 둘 모두와 유사합니다.

포거스: 프로토콜이 CLOS의 영향을 받았다는 것은 분명합니다. 하지만 CLOS에서는 복잡한 클래스 계층(class hierarchies)을 만들 수 있었지만 클로저의 타입과 프로토콜에서는 불가능합니다. 클래스 계층에 관련된 문제점들에 대해서 이야기하고, 프로토콜이 이를 어떻게 해결하는지에 대해서 설명해주실 수 있습니까?

히키: 상속(inheritance)과 계층(hierarchy)은 일종의 논리적 함축(logical implication)이라고 볼 수 있습니다. 예를 들어 X가 Y라면, Y에 대해 참인 모든 명제는 X에 대해서도 참입니다. 이 계층에 다른 것을 추가하려 할 때 문제가 발생하기 시작합니다. Y가 그냥 인터페이스라면 X도 이를 충돌이나 모순 없이 만족시키도록 하는 것은 꽤 수월합니다. 하지만 Y가 동작과 데이터 둘 다면 순식간에 곤란한 상황에 처하게 됩니다. 충돌과 모순이 일어날 가능성이 더 커지고, 상속을 부분적으로 오버라이딩할 수 있는 방법이 보통 있기 때문에 is-a implication이 제한되고 무너지게 되며, 이와 함께 프로그래머가 프로그램에 대해서 추론할 수 있는 능력도 무너져버립니다. 그 뿐 아니라 상속에 기반한 설계 특유의 타입 침입 문제(type-intrusion problem)도 있습니다.

프로토콜과 데이터타입은 일반적으로 구현체 상속을 피하고, 상호운용성을 위해 인터페이스 상속만 지원합니다. 프로토콜은 데이터타입(datatype)을 프로토콜에 직접 연결하는 것을 지원하지만 상속은 지원하지 않습니다. 그리고 프로토콜은 구현체를 직접적으로 조합(composition)하는 것을 지원하는데, 이는 제 생각에는 상속과 동일한 목적을 달성하되 훨씬 더 나은 방식입니다. 인터페이스에다가 프로토콜을 확장해서 구현체 상속을 할 수는 있지만, 그건 상호운용성을 위한 필요악이자 타협이며 사용할 때 주의를 기울여야 합니다.

포거스: 프로토콜과 데이터타입은 클로저를 부트스트랩할 수 있는 기반을 제공합니다. 클로저를 클로저로 구현하는 것이 얼마나 중요한가요?

히키: 클로저를 클로저로 구현할 수 있다는 것이 중요한 이유는 클로저가 스스로의 데이터 구조와 알고리즘을 구현하기 충분한 능력을 가지고 있다는 것을 확인하기 위해서입니다. 새로운 데이터 구조는 항상 이 방식으로 구현하고 있는데, 성공적으로 이루어지고 있습니다. 이전에 구현했던 것을 새로 다시 만든다고 할 때 가장 중요한 부분은 클로저 컴파일러라고 생각합니다. 현재는 거대한 자바 코드인데 유지보수할 때 전혀 즐겁지 않습니다. 그 외에도 컴파일러 안에는 툴링 지원을 개선하기 위해서 다른 방식으로 구현하고 싶은 부분이 몇 가지 있습니다. 그 다음으로 중요한 것은 추상적 개념을 인터페이스에서 프로토콜로 옮기는 것이라고 봅니다. 마지막으로 완전히 부트스트랩을 할 수 있게 되면 이식도 더 쉽게 할 수 있게 될 것입니다.

포거스: 각 호스트 시스템은 당연히 클로저 기능의 서로 다른 부분집합을 지원할텐데, 이식을 어떻게 통합할 생각입니까?

히키: 그럴 생각은 없습니다. 거대한 프로그램을 한 호스트 시스템에서 다른 시스템으로 이식할 수 있도록 하는 것은 여태까지도 클로저의 목적이 아니었고, 앞으로도 아닐 것입니다. 그건 필요로 하는 사람도 거의 없어 그냥 시간 낭비일 뿐입니다. 지금은 호스트 시스템을 바꿀 때마다 언어도 종종 바꿔야 합니다. 자바에서 C#이나 자바스크립트로 바꾸는 것처럼 말이죠. 제가 추구하는 방식은 완전한 이식성 레이어(portability layer)가 조금 부족한 것을 제외하면 그 방식보다 더 나은 방식입니다. 클로저와 클로저 코어 라이브러리, 그리고 타깃 호스트 시스템에 대한 지식만 가지고도 일을 할 수 있도록 한다는 개념이지요. 클로저 코어와 같이 IO와 무관한 라이브러리는 당연히 여러 호스트 시스템에서 사용할 수 있습니다. JVM과 CLR은 대충 동일한 수준의 기능을 가지고 있고, 자바스크립트 호스트에 어떤 제약사항이 있는지는 살펴봐야 합니다.

포거스: 클로저로 구현하는 클로저의 일부로 “클로저 커널”을 공식적으로 정의할 생각입니까?

히키: 아닐 것 같습니다. 이식체가 몇 개 만들어지고 난 다음에는 공통된 부분에 그런 이름표를 붙일 수도 있겠지만 실제로 여러 개의 호스트 시스템을 파악하고 성공적으로 이식하기도 전에 그렇게 공식화를 시도하는 것은 어리석은 짓이라 생각합니다.

포거스: 가장 좋아하는 툴은? 에디터? 버전 컨트롤? 디버거? 드로잉 툴? IDE?

히키: Circus Ponies NoteBook, OmniGraffle, 해먹.

포거스: 테스트 주도 개발에 반대하는 것으로 알려져 있는데, 그에 대한 입장을 명확히 설명해주실 수 있겠습니까?

히키: TDD에 ‘반대한’ 적은 없습니다. 제가 한 말은, 인생은 짧고 하루에는 제한된 양의 시간만 있다는 것입니다. 그래서 우리는 시간을 어떻게 쓸 지 선택해야 합니다. 테스트를 작성하는데 시간을 썼다는 것은 다른 일을 하는데 시간을 쓰지 않았다는 것입니다. 우리는 양적, 질적으로 최대한의 결과를 내기 위해서는 어떻게 시간을 쓰는 것이 최선인지를 각자 판단해야 합니다. 결과물을 극대화하기 위해서 전체 시간의 50퍼센트를 테스트를 작성하는데 써야한다고 판단한 사람이라면 그래도 괜찮습니다. 하지만 저에게 있어서는 틀린 판단이라고 생각합니다. 저는 그 시간을 차라리 문제에 대해서 생각하는데 쓰겠습니다. 저에게 있어서는 그게 다른 어떤 시간 활용법보다 더 나은 해결책과 더 적은 결함을 만들어낼 수 있는 방식이라고 확신합니다. 안 좋은 설계에 완전한 테스트 스윗이 달려 있어도 그건 여전히 안 좋은 설계입니다.

포거스: 클로저는 에펠(Eiffel)의 계약 기반 프로그래밍(contract programming) 중 일부에 해당하는 함수 제약(function constraint) 기능을 선행조건과 후행조건(pre- and post-condition) 확인을 통해 제공합니다. 이런 제약이 유닛 테스팅을 불필요하게 만드나요, 아니면 보완하나요?

히키: 유닛 테스트를 보완합니다. 함수 제약은 코드가 작성된 시점에서의 의도를 문서화하고, 프로그램 내에서 선택적으로 실행할 수 있는 등의 유용한 특성을 지니고 있습니다.

포거스: 클로저에 어떤 기능을 추가할지에 대한 결정은 해당 기능의 구현체적, 태생적 복잡성과는 독립적으로 내리고 있는 것처럼 보입니다. 예를 들어 스트림은 클로저에 통합되기 직전에 완전히 폐기되어버렸습니다. 마찬가지로 스코프를 이해하고 구현하는 것은 꽤 간단하지만, 그 기능도 마찬가지로 취소되었거나 최소한 대대적으로 연기된 것처럼 보입니다. 구체적으로는 해당 두 기능을 포함시키지 않기로 결정한 이유, 그리고 전반적으로는 클로저에 기능을 추가할 때 가장 중요하게 보는 기준이 무엇인지 설명해주실 수 있나요?

히키: 기본적인 입장은 기능을 추가하지 않는 것입니다. 복잡성은 중요합니다.

스트림의 경우 API에서 골치아픈 것들을 노출시켰는데, 저는 그게 거북했습니다. 스트림을 만들게 된 계기가 되었던 발상은 이제 전반적으로 더 알맞는 개념인 포드(pods)로 옮겨갔습니다. 포드, 일시성(transient), 참조(reference) 등 여러 기능들이 상호작용하므로 그 중 하나만 떼어놓고 살펴볼 수는 없습니다. 스코프는 구현하기 쉬워 보일 수도 있지만, 쉬운 구현 방식은 모두 스레드풀 스레드에 관하여 vars와 바인딩이 가지는 한계와 동일한 한계를 지니고 있습니다. 그 부분과 바인딩을 어떻게 개선할지에 대해 생각해둔 방안이 있으며, 스코프를 내놓기 전에 그 일부터 진행해야할 수도 있습니다. 그래도 스코프는 여전히 고려대상입니다.

제가 바라는 것은 모든 새로운 기능이 실제로 사람들이 필요로 할 뿐 아니라, 제가 흡족해할만한 방식으로 설계되는 것입니다. 이런 과정에는 실험적인 연구와 고찰할 시간이 필요합니다. 저는 더 나은 발상을 구상할 권한을 가지고 있고, 가끔은 구상을 하기 위해 의도적으로 기다리기도 합니다. 저는 제가 주로 특정 기능이 아니라, 기능이 해결해주는 문제에 노력을 쏟고 있다고 생각하고 싶습니다. 스코프는 기능일 뿐이고 문제는 자원 관리입니다. 스트림과 포드도 기능일 뿐이고 문제는 프로세스입니다. 문제에 노력을 쏟는 과정에서 기능에 대한 발상을 떠올리거나 가끔은 폐기하게 되는 것입니다.

포거스: 이전에 같이 일을 해본 사람들에게 물어봤더니, 당신을 문제 해결과 디버깅의 달인이라고 표현하더군요. 어떻게 디버그를 합니까?

히키: 과학적 방법론을 사용한다고 할 수 있겠군요. 먼저 주어진 정보를 바탕으로 상황을 분석하는데, 이 때 정보를 더 모을 수도 있습니다. 알고 있는 사실을 바탕으로 무엇이 잘못 되었는지에 대한 가설을 세우고, 가설을 시험할 수 있는 가장 작은 실험을 찾은 뒤, 이를 실험해보세요. 이 때 가능하다면 격리된 재현 사례를 종종 만들어보게 될 것입니다. 그 작은 시험으로 가설을 검증했을 경우에만 전체 어플리케이션에서 그 문제를 찾아봅니다. 검증에 실패했다면 질적, 양적으로 더 나은 자료를 수집해서 다른 가설을 세웁니다. 광범위한 환경에서 문제를 해결하려 하거나, 디버거를 실행하거나, 단순히 어떤 효과를 내는지를 보기 위해서 변화를 줘보는 것 등은 피하려 합니다.

가상 이상적인 상황은 알려진 사실에 유일하게 들어맞는 가설을 세웠기 때문에 이미 컴퓨터를 만지기도 전에 문제를 해결했다고 확신할 수 있는 경우입니다.

포거스: 명령형, 객체 지향형 코드를 디버깅하는 것과 클로저 코드를 디버깅하는 것 사이에 근본적인 차이가 있습니까?

히키: 근본적인 차이는 없지만 함수형 코드는 더 국지적이기 때문에 디버그하기가 훨씬 수월합니다.

포거스: 스레드 동시성 측면에서 클로저는 다양한 형태의 참조 타입을 갖추고 있고, 이들은 각각 다른 상황 하에서 사용될 수 있어 매우 탄탄한 기능성을 제공합니다. 현재 클로저가 제공하는 동시성 관련 기능에 만족하나요, 아니면 현재 제공되는 참조 모델을 더 확장하거나 분산형 동시성에 뛰어들 생각도 있나요?

히키: 저는 점점 이 주제를 동시성 자체만에 대한 것이라기보다는 상태/정체성(identity)/값/시간/프로세스에 대한 것이라고 보게 되었습니다. 이는 동시성 프로그램에는 당연히 매우 중요합니다. 저는 최소한 하나의 참조 타입을 추가할만한 여지는 있다고 봅니다. 일시적인 프로세스를 통해서 어떤 값이 다른 값으로부터 만들어졌을 때, 해당 프로세스가 그 값 그리고/또는 다수의 참여자를 가질 수 있도록 해주는 구조체가 있는 것도 괜찮을 것입니다. 이는 사람들이 락을 사용해서 즉석으로 그때그때 사용하는 방식인데, 이를 참조와 유사한 포드라는 구조체로 감싸서 다른 참조 타입들처럼 자동화하고, 동시에 명시적이고 안전하게 만들 수 있을 것입니다.

분산형 동시성은 언어의 영역이라고 보지 않습니다. 또한 대부분의 어플리케이션에는 직접적으로 연결된 분산된 객체들보다는 일종의 메시지 큐 방식이 더 적합하다고 생각합니다.

포거스: 병렬성을 지원하기 위한 기초 요소들(primitives)이 존재하기는 하지만 이 부분에서 클로저는 아직 발전의 여지가 많이 있습니다. 포크-조인이나 데이터플로우 등을 위한 고수준 병렬성 라이브러리를 추가할 계획이 있습니까?

히키: 네, 기존 데이터 구조에 포크-조인 기반 병렬성 맵/리듀스/필터 등을 지원할 계획도 있고, 구현해본 작업물도 조금 있습니다.

포거스: 고수준 언어를 최적화하는 것은 더 어렵습니까?

히키: 모르겠습니다. 제가 아는 것은 가상화, 반응성 런타임, 동적 컴파일 등을 더 사용할수록 그 런타임에서 돌아가는 모든 언어에 대한 결정론적 성능 모델을 만들기가 점점 더 어려워진다는 것입니다. 이는 아마 수동적인 최적화를 통해 얻을 수 있는 것보다 뛰어난 성능을 얻는 것에 대한 대가라고 볼 수 있을 것입니다.

포거스: 상태, 시간, 정체성에 대한 클로저의 개념을 설명하는 과정에서 알프레드 노스 화이트헤드(Alfred North Whitehead)의 철학, 특히 그의 저서인 Process and Reality와 Science and the Modern World를 인용한 적이 있습니다. 개발자로써 우리가 화이트헤드의 철학, 그리고 철학 전반으로부터 배울 수 있는 것은 무엇이 있을까요? 소프트웨어 개발자 교육에 철학의 입지가 있을까요?

히키: 저는 화이트헤드의 철학이나 형이상학의 지지자가 아니고, 이를 전부 이해하고 있다고 말할 깜냥도 없습니다. JVM 언어 회담에서 할 기조 발표를 준비하고 있을 때 클로저 내에서 언어에 종속적이지 않은 핵심 개념들을 찾아내려 노력하고 있었습니다. 그러다가 학부 때 공부한 화이트헤드 철학이 생각나서 그의 책을 몇 권 살펴보았습니다. 아니나 다를까 그는 시간, 프로세스, 불변성 같은 제 발표 주제들을 깊이 있게 다루고 있었습니다. 화이트헤드는 인용하기 좋은 사람이었고, 그래서 제 발표의 ’영웅’으로 삼았습니다. 하지만 화이트헤드는 클로저에 영감을 준 사람은 아닙니다. 연관성은 모두 나중에 우연히 발견했습니다. 그렇다고 해도 연결고리는 놀라울 정도로 많았습니다.

우리가 객체 시스템 같은, 세상을 간소화한 모델을 프로그래밍 구성체로 만들어 사용하는 한, 어떤 방식으로든 세상을 더 폭넓게 이해하는 것은 프로그래머에게 도움이 될 것이라고 생각합니다.