마틴 오더스키와의 대화를 통해 스칼라 프로그래밍 언어가 탄생하게 된 역사와 배경을 살펴본다.
The Origins of Scala
Scala의 기원
빌 베너스(Bill Venners), 프랭크 소머스(Frank Sommers) 인터뷰
2009년 5월 4일
요약
마틴 오더스키가 빌 베너스와 함께 스칼라(Scala) 프로그래밍 언어가 탄생하게 된 역사와 배경에 대해 이야기한다.
JVM을 위한 범용 객체지향 함수형 언어인 스칼라는 로잔연방공과대학교(EPFL)의 교수인 마틴 오더스키의 작품이다. 이 다부작 인터뷰 시리즈의 첫 번째 기사에서, 마틴 오더스키는 Artima의 빌 베너스와 함께 스칼라의 역사와 기원에 대해 논의한다.
빌 베너스: 처음부터 시작해보죠. 어떻게 해서 프로그래밍 언어에 처음 관여하게 되었나요?
마틴 오더스키: 제가 가장 좋아했던 주제는 항상 컴파일러와 프로그래밍 언어였습니다. 제가 처음 컴파일러가 무엇인지 알게 된 것은 1980년 학부생 때였는데, 그걸 알게 되자마자 바로 하나 만들어 보고 싶어졌습니다. 그 당시 제가 어떻게든 살 수 있을 법한 유일한 컴퓨터는 RAM이 1킬로바이트인 Sinclair ZX 80뿐이었습니다. 실제로 그걸로 한번 시도해볼까 아주 가까이까지 갔었는데, 다행히도 곧 더 강력한 머신인 Osborne-1을 쓸 수 있게 되었습니다. Osborne-1은 세계 최초의 "휴대용"(실제로는 들고 다닐 수 있다는 의미의) 컴퓨터였고, 90도 기울어진 재봉틀처럼 생겼습니다. 5인치 화면에 한 줄에 52개의 아주 작은 문자를 표시할 수 있었죠. 하지만 56킬로바이트의 사용 가능한 RAM과 각각 90K 용량의 플로피 드라이브 두 개를 갖춘, 당시로서는 매우 인상적인 기계였습니다.
그 시절에 저는 대학에서 피터 졸리히(Peter Sollich)라는 다른 학생과 함께 시간을 보내곤 했습니다. 우리는 모듈라-2(Modula-2)라는 새로운 언어에 대해 읽었는데, 아주 우아하고 잘 설계된 언어라고 느꼈습니다. 그래서 8비트 Z80 컴퓨터용 모듈라-2 컴파일러를 만들자는 계획을 세우게 되었습니다. 다만 작은 문제가 있었는데, Osborne에 기본으로 제공되던 유일한 언어가 마이크로소프트 베이직(Microsoft Basic)이었다는 점이었습니다. 이 언어는 우리가 하려던 작업에는 전혀 적합하지 않았습니다. 매개변수를 받는 프로시저조차 지원하지 않았고, 전역 변수만 있었기 때문입니다. 당시 다른 컴파일러들은 우리 형편에 비해 너무 비쌌습니다. 그래서 우리는 고전적인 부트스트래핑 기법을 적용하기로 했습니다. 피터가 Z80 어셈블리 언어로 파스칼의 작은 부분집합에 대한 첫 번째 컴파일러를 작성했고, 우리는 이 컴파일러를 사용해 조금 더 큰 언어를 컴파일했고, 그런 식으로 여러 세대를 거듭하면서 점차 확장해 마침내 모듈라-2 전체를 컴파일할 수 있게 되었습니다. 이 컴파일러는 인터프리트되는 바이트코드와 Z80 바이너리를 모두 생성할 수 있었습니다. 당시 어떤 시스템보다도 바이트코드가 가장 compact했고, 바이너리 버전은 8비트 컴퓨터용으로 가장 빨랐습니다. 그 시대로 보았을 때 꽤 강력한 시스템이었죠.
우리가 컴파일러를 거의 완성했을 무렵, 볼랜드(Borland)가 터보 파스칼(Turbo Pascal)을 출시했고, 모듈라-2 시장에도 진출하는 것을 검토하고 있었습니다. 실제로 볼랜드는 우리가 만든 모듈라-2 컴파일러를 CP/M용 터보 모듈라-2(Turbo Modula-2)라는 이름으로 판매하기로 했고, 동시에 IBM PC 버전은 그들이 따로 개발하기로 했습니다. 우리는 IBM PC 버전도 우리가 만들겠다고 제안했지만, 그들은 이미 맡아둔 팀이 있다고 말했습니다. 안타깝게도 그 버전은 계획보다 훨씬 오래 걸렸습니다. 실제로 그 제품이 나온 것은 3~4년 뒤였는데, 그 무렵에는 구현 팀이 회사를 떠나 있었고, 그 컴파일러는 탑스피드 모듈라-2(TopSpeed Modula-2)라는 이름으로 알려지게 되었습니다. IBM PC 버전이 없는 상황에서, 볼랜드는 터보 모듈라-2에 마케팅 역량을 거의 쏟지 않았고, 그래서 그 제품은 상당히 마이너한 위치에 머물렀습니다.
우리가 모듈라-2 컴파일러를 완성했을 때, 볼랜드는 피터와 저 둘 다를 바로 채용하겠다고 제안했습니다. 피터는 그곳에 합류했고, 저도 거의 합류할 뻔했지만, 아직 수업을 1년 더 들어야 했고 석사 프로젝트도 남아 있다는 문제가 있었습니다. 당시 저는 대학을 중퇴할까 하는 유혹을 강하게 느꼈습니다. 결국 저는 대학에 남기로 결심했습니다. 제 석사 프로젝트(증분 파싱에 관한 것이었습니다)를 하는 동안, 저는 연구를 정말 좋아한다는 사실을 깨달았습니다. 결국 저는 볼랜드에 들어가 컴파일러를 만드는 길을 포기하고, 대신 파스칼과 모듈라-2의 발명가인 니클라우스 비르트(Niklaus Wirth)와 함께 취리히 연방 공과대학교(ETH Zurich)에서 박사 과정을 밟기로 했습니다.
빌 베너스: 스칼라는 어떻게 탄생했나요? 그 역사는 어떤가요?
마틴 오더스키: 제가 취리히에 머물던 말기인 1988/89년 무렵, 저는 함수형 프로그래밍에 깊이 빠져들었습니다. 그래서 계속 연구를 이어갔고, 결국 독일 카를스루에에서 대학 교수가 되었습니다. 처음에는 콜바이니드 람다 계산(call-by-need lambda calculus) 같은 프로그래밍의 좀 더 이론적인 측면을 연구했습니다. 그 작업은 당시 글래스고 대학교에 있던 필 와들러(Phil Wadler)와 함께 했습니다. 어느 날 필이 제게 말하길, 그의 그룹에 있던, 여러 소문을 잘 알고 있던 조교 한 명이 자기가 새로운 언어에 대해 들었다고 했답니다. 아직 알파 단계인 언어였는데, 이름은 자바(Java)였습니다. 그 조교가 필에게 이렇게 말했죠. "이 자바라는 걸 보세요. 이식성이 있어요. 바이트코드가 있고, 웹에서 돌아가고, 가비지 컬렉션도 있습니다. 이건 당신을 완전히 묻어버릴 거예요. 당신은 어떻게 할 건가요?" 필은, 글쎄, 일리가 있는 말일지도 모르겠다고 생각했습니다.
우리가 내린 답은, 필 와들러와 제가 함수형 프로그래밍의 몇 가지 아이디어를 자바 세계로 가져오기로 했다는 것이었습니다. 그 결과물이 바로 피자(Pizza)라는 언어였는데, 이 언어는 함수형 프로그래밍으로부터 제네릭, 고차 함수, 패턴 매칭이라는 세 가지 기능을 도입했습니다. 피자의 첫 배포는 자바가 나온 지 1년 뒤인 1996년에 이루어졌습니다. 피자는 JVM 플랫폼 위에 함수형 언어의 기능을 구현할 수 있다는 점을 보여주었다는 면에서 어느 정도 성공을 거두었습니다.
그 후 우리는 썬(Sun) 코어 개발 팀의 길라드 브라차(Gilad Bracha)와 데이비드 스타우트마이어(David Stoutamire)와 접촉하게 되었습니다. 그들이 말하길, "우리는 당신들이 하고 있는 제네릭 쪽 작업에 정말 관심이 있습니다. 그 부분만을 다루는 새로운 프로젝트를 같이 해봅시다." 그렇게 해서 GJ(Generic Java)가 탄생했습니다. 우리는 1997/98년에 GJ를 개발했고, 6년 후에 자바 5의 제네릭으로 편입되었습니다. 그 과정에서 우리가 당시에는 넣지 않았던 몇 가지 기능이 추가되었습니다. 특히, 자바 제네릭의 와일드카드(wildcards)는 나중에 길라드 브라차와 오르후스(Aarhus) 대학교 사람들에 의해 독립적으로 개발되었습니다.
우리가 만든 제네릭 확장은 6년 동안 보류 상태였지만, 썬은 제가 GJ를 위해 작성한 컴파일러에 더 큰 관심을 갖게 되었습니다. 그 컴파일러가 썬이 처음 만든 자바 컴파일러보다 더 안정적이고 유지보수하기도 쉬운 것으로 드러났기 때문입니다. 그래서 썬은 GJ 컴파일러를 2000년에 출시된 1.3 버전부터 표준 javac 컴파일러로 삼기로 결정했습니다.
마틴 오더스키: 자, 피자와 GJ 경험을 하던 동안 저는 때때로 좌절감을 느끼곤 했습니다. 자바는 이미 존재하는 언어이고, 매우 강력한 제약이 있기 때문입니다. 그 결과로, 저는 많은 것들을 제가 하고 싶던 방식, 즉 제가 옳다고 확신하던 방식대로 할 수가 없었습니다. 그래서, 제 작업의 초점이 본질적으로 자바를 더 좋게 만드는 데 맞추어져 있던 시기가 지나자, 한 발 물러날 때가 되었다고 느꼈습니다. 완전히 백지 상태에서 시작해서, 자바보다 더 나은 것을 설계할 수 있을지 보고 싶었습니다. 하지만 동시에 저는 완전히 무(無)에서 시작할 수 없다는 것도 알고 있었습니다. 기존 인프라, 즉 라이브러리나 도구 같은 것들과 연결되어야만 했습니다. 그렇지 않으면, 아무 기반도 없이 스스로 부트스트랩하는 것은 실질적으로 불가능하기 때문입니다.
그래서 저는 비록 자바와는 다른 언어를 설계하고 싶었지만, 항상 자바 인프라—JVM과 그 라이브러리들—와 연결되도록 하자고 결심했습니다. 그게 기본 아이디어였습니다. 마침 그 무렵 제가 EPFL의 교수가 되는 기회를 얻게 되었는데, EPFL은 독립적인 연구를 하기에 훌륭한 환경을 제공합니다. 저는 외부 연구비를 쫓아다닐 필요 없이 일할 수 있는 작은 연구팀을 꾸릴 수 있었습니다.
처음에는 꽤 급진적이었습니다. 우리는 조인 계산법(join calculus) 이라는, 매우 아름다운 동시성 모델 위에 뭔가를 구축하고자 했습니다. 우리는 이 조인 계산법의 객체지향 버전인 Functional Nets와, Funnel이라는 언어를 만들었습니다. 하지만 시간이 지나면서 Funnel이 아주 "순수한" 언어이다 보니, 꼭 실용적이지는 않다는 사실을 알게 되었습니다. Funnel은 아주 작은 코어 위에 구축된 언어였습니다. 사람들에게 당연하게 여겨지는 많은 것들(예를 들어 클래스나 패턴 매칭 같은 것들)이 이 코어로의 인코딩을 통해서만 제공되었습니다. 이는 학문적인 관점에서 보면 매우 우아한 기법입니다. 하지만 실제로는 그다지 잘 작동하지 않았습니다. 초보자들은 필요한 인코딩을 상당히 어렵게 느꼈고, 전문가들은 매번 같은 인코딩을 반복해야 하는 것을 지루해했습니다.
그 결과 우리는 다시 처음부터 시작하기로 정했고, 매우 순수한 학술 언어인 Funnel과, 매우 실용적이지만 몇몇 부분에서는 제약이 있던 GJ의 중간 어디쯤에 위치한 무언가를 만들고자 했습니다. 우리는 실용적이고 유용하면서도, 자바로는 달성할 수 없었던 것들을 더 발전된 형태로 구현하는 언어를 만들고 싶었습니다. 우리는 이 언어를 2002년 즈음부터 작업하기 시작했고, 그것을 스칼라(Scala)라고 부르게 되었습니다. 첫 공개 릴리스는 2003년에 있었습니다. 2006년 초에는 비교적 큰 재설계가 있었고, 그 이후로 스칼라는 성장과 안정화를 계속해 왔습니다.
빌 베너스: 자바와의 역호환성을 유지해야 한다는 제약이 때때로 답답했다고 했습니다. 그 제약을 지켜야 했기 때문에 할 수 없었던 일들의 구체적인 예를 들 수 있을까요? 그리고 그 뒤에는 소스 수준에서는 호환되지 않지만 바이너리 수준에서는 호환되는 새로운 것을 만들면서 비로소 할 수 있게 된 일들은 어떤 것들인가요?
마틴 오더스키: 제네릭 설계에서 극도로 강한 제약이 많았습니다. 가장 강력하고, 다루기 어려웠던 제약은, 기존의 제네릭이 없는 자바와 완전히 역호환되어야 한다는 것이었습니다. 사연은 이렇습니다. 컬렉션 라이브러리가 1.2와 함께 막 출시되었고, 썬은 단지 제네릭을 도입했다는 이유만으로 완전히 새로운 컬렉션 라이브러리를 내보낼 생각이 없었습니다. 그래서 기존 코드가 아무런 문제 없이 그대로 동작해야만 했습니다.
그 때문에 다소 보기 좋지 않은 부분들이 생겼습니다. 항상 제네릭 타입과 제네릭이 아닌 타입, 이른바 raw 타입 을 함께 가져가야 했습니다. 그리고 배열이 하는 일을 바꿀 수 없었기 때문에 확인되지 않은(unchecked) 경고들이 생기게 되었습니다. 가장 중요한 것은 배열과 관련해 하고 싶었던 많은 일들을 할 수 없었다는 점입니다. 예를 들어, 타입 매개변수 T를 갖는 배열, 즉 타입을 알 수 없는 어떤 것의 배열을 만드는 것은 불가능했습니다. 그건 할 수 없었습니다. 나중에 스칼라에서는 그런 것을 어떻게 할 수 있는지 알아냈지만, 그건 스칼라에서 배열이 공변(covariant)이라는 요구사항을 버릴 수 있었기 때문에 가능했습니다.
빌 베너스: 자바의 공변 배열(covariant arrays) 문제를 좀 더 자세히 설명해 줄 수 있나요?
마틴 오더스키: 자바가 처음 나왔을 때, 빌 조이(Bill Joy), 제임스 고슬링(James Gosling), 그리고 자바 팀의 다른 멤버들은 자바에 제네릭이 있어야 한다고 생각했습니다. 하지만 제대로 설계할 시간이 없었죠. 그래서 적어도 초기에는 자바에 제네릭이 없을 것이므로, 대신 배열을 공변으로 만들어야 한다고 느꼈습니다. 공변이라는 것은, 예를 들어 String의 배열이 Object의 배열의 서브타입이 된다는 의미입니다. 그 이유는, 예를 들어 "제네릭" 정렬 메서드를 하나 작성해서 Object 배열과 비교자를 받아 이 Object 배열을 정렬하게 만들고, 여기에 String 배열을 그대로 넘길 수 있도록 하고 싶었기 때문입니다. 그런데 이런 방식은 일반적으로 타입 안전하지 않다는 것이 드러났습니다. 그래서 자바에서는 배열 저장 예외(array store exception)가 발생할 수 있는 겁니다. 그리고 바로 그 점 때문에, 이런 설계가 배열에 대한 제대로 된 제네릭 구현을 막게 된다는 사실도 밝혀졌습니다. 그래서 자바 제네릭에서는 배열이 전혀 제대로 동작하지 않습니다. List<String>의 배열을 만들 수가 없습니다. 불가능합니다. 평생 raw 타입, 즉 단순히 List의 배열만 쓸 수밖에 없습니다. 이것은 일종의 원죄(original sin) 같은 것이었습니다. 그들은 매우 빠르게 무언가를 해버렸고, 빠른 임시방편이라고 생각했지만, 나중에 이어지는 모든 설계 결정을 망쳐 버렸습니다. 그래서 같은 함정에 다시 빠지지 않으려면, 우리는 자바와의 상위 호환성을 유지하지 않기로 결단을 내려야 했습니다. 즉, 우리가 다르게 하고 싶은 부분들이 있다는 사실을 인정해야 했습니다.
마틴 오더스키와의 대화 두 번째는 5월 11일 월요일에 이어집니다. Artima.com에 새로 올라오는 기사를 매주 짧은 이메일로 받아보고 싶다면, 계정 설정에서 Artima 뉴스레터에 체크해 구독해 주세요.
Resources --------- 스칼라 프로그래밍 언어 웹사이트는 다음을 참조하십시오.
Funnel 언어에 대한 더 많은 정보는 여기에서 볼 수 있습니다.
Functional Nets에 대한 더 많은 정보는 여기에서 볼 수 있습니다.
조인 계산법(Join calculus)에 대해서는 위키피디아에서 볼 수 있습니다.
http://en.wikipedia.org/wiki/Join-calculus
필 와들러(Phil Wadler)의 홈페이지는 여기입니다.
http://homepages.inf.ed.ac.uk/wadler/
니클라우스 비르트(Niklaus Wirth)의 위키피디아 항목:
http://en.wikipedia.org/wiki/Niklaus_Wirth
소스포지(SourceForge)에 있는 피자(Pizza) 언어. 한 조각 맛보는 건 어떨까요?
http://pizzacompiler.sourceforge.net/
Generic Java Language Extension(GJ):
http://homepages.inf.ed.ac.uk/wadler/pizza/gj/
모듈라-2(Modula-2) 홈페이지는 여기입니다.
어떤 생각이 있으신가요? 독자들이 이 기사에 대해 이미 76개의 댓글을 남겼습니다. 당신도 의견을 남겨 보시겠습니까?
빌 베너스(Bill Venners)는 Artima, Inc.의 대표로, Artima Developer(www.artima.com)를 발행하고 있습니다. 그는 자바 플랫폼 아키텍처와 내부 구조에 대한 프로그래머 지향 개설서인 『Inside the Java Virtual Machine』의 저자입니다. JavaWorld 잡지에 연재한 그의 인기 칼럼은 자바 내부 구조, 객체지향 설계, Jini를 다루었습니다. Jini 커뮤니티가 시작될 때부터 활발히 활동해 온 빌은, Jini 서비스에 사용자 인터페이스를 연결하는 사실상의 표준 API가 된 ServiceUI API를 만든 Jini 커뮤니티의 ServiceUI 프로젝트를 이끌었습니다. 빌은 또한 스칼라와 자바 개발자를 위한 오픈 소스 테스트 도구인 ScalaTest의 리드 개발자이자 설계자이며, 마틴 오더스키, 렉스 스푼(Lex Spoon)과 함께 『Programming in Scala』의 공저자이기도 합니다.
프랭크 소머스(Frank Sommers)는 Artima Developer의 에디터입니다. 그는 금융 서비스 업계를 위한 협업 및 워크플로 도구를 제공하는 회사인 Autospaces, Inc.의 창립자이자 대표이기도 합니다.