원문: The Humble Programmer by Edsger W. Dijkstra, Communications of the ACM, 1972년 10월, Volume 15, Number 10, 859–866.
GOTO-less 프로그래밍, 세마포어, 최단경로 알고리즘 등등 전산 분야 공부한 사람이라면 한 번쯤 이름을 들어봤을 전산학자 Dijkstra가 1972년 튜어링 어워드 수상했을 때의 강연
긴 우연의 연속으로 1952년 어느 봄날 아침 내가 프로그래밍직에 공식적으로 발을 들였다. 내가 아는 한 네덜란드 최초의 직업 프로그래머가 된 것이다. 돌이켜 보면 가장 놀라운 건 내가 사는 곳에서 얼마나 느리게 프로그래밍 직군이 나타났는가 하는 점이다. 지금 생각해 보면 믿기 어려울 정도로 느린 등장이었다. 그러나 의심할 여지 없이 느린 그 시절의 두 가지 일화가 내게는 고마운 기억으로 남아 있다.
내가 3년 정도 프로그래밍을 경험한 후 암스테르담 수학 센터의 상사님이셨던 van Wijngaarden과 상담을 한 적이 있었고, 그건 내 평생 그에게 감사하게 되는 계기가 된 시간이었다. 그 당시 나는 Leiden 대학에서 이론 물리학 공부를 병행하고 있었는데, 두 가지 활동을 함께하는 것이 점점 어렵게 느껴져서 결단이 필요했다. 즉 프로그래밍을 중단하고 진짜 존경받는 이론 물리학자가 되거나, 아니면 최소한의 노력으로 공식적인 물리학 공부를 마치고 다음은... 뭐가 되겠다고? 프로그래머? 이걸 어엿한 직업이라고 할 수 있나? 그나저나 프로그래밍이 뭐지? 이게 지적으로 존중할 만한 하나의 학문임을 뒷받침하는 지식 체계가 있긴 한 건가? 자신의 전문 직능에 대해 질문받았을 때, 적어도 진공관에 대해서는 또는 증폭기에 대해서는 모든 것을 빠삭하게 안다고 답할 수 있는 하드웨어 분야 동료들을 내가 무척 부러워했던 기억이 생생하다. 같은 질문에 대해 나는 빈손으로 서 있는 느낌이었다. 걱정이 가득한 내가 van Wijngaarden의 사무실 문을 두드려 잠시 그와 얘기할 수 있는지 물었고, 몇 시간 후 그의 사무실을 떠날 때는 완전히 다른 사람이 되어 있었다. 참을성 있게 내 고민을 들은 그는 그때까지 프로그래밍 분야가 그다지 정립되지 않았다는 점에 동의했다. 하지만 자동 컴퓨터는 잠깐 왔다 사라질 게 아니고 단지 시작점에 있으며, 자네가 앞으로 프로그래밍을 존경할 만한 분야로 만드는 사람들 중 하나이지 않겠느냐는 설명을 조용히 이어갔다. 이게 내 인생의 전환점이 되었고, 나는 최대한 빠르게 공식적인 물리학 공부를 끝마쳤다. 이 이야기의 한 가지 교훈은 우리가 젊은이들에게 조언할 때는 매우 신중해야 한다는 것이다. 받아들이는 사람도 간혹 있으니 말이다!
2년 후인 1957년 내가 결혼을 했다. 네덜란드 결혼식에서는 직업을 밝히게 되어 있어서 ‘프로그래머’라고 말했지만, 암스테르담시 당국은 그러한 직업이 없다는 이유로 받아들이지 않았다. 믿기 힘들겠지만 내 결혼 기록부의 직업란에는 ‘이론 물리학자’라는 터무니없는 단어가 쓰여 있다.
내 나라에서 프로그래밍 직업이 얼마나 느리게 등장했는지에 대한 이야기는 이쯤 해 두겠다. 이후 내가 더 많은 세상을 보았고, 다른 나라들도 시일이 조금 앞서거니 뒤서거니 할 뿐 성장 패턴이 매우 비슷하다는 인상을 받았다.
오늘날의 상황을 더 잘 이해하기 위해서 내가 과거 모습을 좀 더 자세히 짚어 보겠다. 이 분석을 통해 프로그래밍의 진정한 본질에 대해 얼마나 많은 착각이 과거에 만연했는지 보게 될 것이다.
처음 출현한 자동 전자 컴퓨터는 유일무이한 기계 한 대가 전부였고, 도전적이고 실험적 정신이 물씬 풍기는 연구실 환경에 놓여 있었다. 자동 컴퓨터에 대한 비전이 등장했을 때 당시 사용 가능한 전자 기술로 이를 실현하는 것은 엄청난 도전이었으며, 그러한 기상천외한 기기를 만들기로 한 그룹의 용기가 대단했음을 분명 부인할 수 없다. 워낙 기상천외하다보니 돌이켜보면 그런 1 세대 기계들이, 적어도 일부는, 실제 작동했다는 게 놀라울 따름이다. 가장 압도적인 문제가 기계를 작동 상태로 만들고 유지하는 일이었다. 자동 컴퓨팅의 물리적 측면에 대한 집착은 이 분야의 오래된 과학 학회명에서 여전히 찾아볼 수 있다. 예를 들어, ‘컴퓨팅 기계 협회(Association for Computing Machinery)’ 또는 ‘영국 컴퓨터 협회(British Computer Society)’ 같은 이름에는 물리 장비에 대한 명시적 언급이 담겨있다.
그렇다면 가엾은 프로그래머는 어찌 되었나? 솔직히 말해서 그들은 거의 눈에 띄지 않았다. 첫째로 최초 출현 기계들은 덩치가 너무 커서 이동이 거의 불가능했고, 또한 광범위한 유지 보수를 필요로 했기 때문에 기계를 개발한 실험실이 자연스럽게 기계를 사용하는 장소가 되었다. 둘째로 프로그래머의 일이 뭔가 그럴싸하게 눈에 보이는 게 아니었다. 방문자들에게 코딩 종이 몇 장을 흔드는 것보다 기계를 보여주는 편이 훨씬 더 볼만한 구경거리를 제공했다. 그러나 무엇보다도 프로그래머 스스로가 자신의 일에 대해 매우 겸손한 견해를 가지고 있었다. 즉, 그 대단한 기계의 존재로 인해 자신의 일이 비로소 의미를 가진다고 생각했다. 그것이 유일무이한 기계였으므로 본인의 프로그램이 단지 국부적 의미만 가진다는 것을 잘 알고 있었고, 또한 기계 수명이 명백히 한정적이었기 때문에 자신의 작업이 지속적인 가치가 거의 없다는 것도 알았다. 마지막으로 프로그래머가 자기 일에 대해 가지는 태도에 깊은 영향을 미친 또 다른 사정이 있었다. 이 기계가 신뢰성이 떨어지는 외에도 대개 너무 느리고 메모리가 작았으며(즉 꽉 끼는 신발을 신은 상황), 기계의 다소 기묘한 오더 코드(오퍼레이션 코드)가 전혀 예상치 못한 구조를 수용하기도 했다. 그 시절 많은 똑똑한 프로그래머들은 정교한 트릭을 고안해 불가능한 것을 기계 제약 내로 용케 밀어 넣는 데서 엄청난 지적 만족감을 얻었다.
내가 지금 설명할, 그리고 나중에 다시 언급하게 될, 프로그래밍에 대한 두 가지 견해가 그 시절부터 시작되었다. 한 가지 견해는 정말 유능한 프로그래머는 머리 쓰는 문제를 즐기고 영리한 트릭을 매우 좋아해야 한다는 것이고, 또 다른 견해는 프로그래밍이란 이런저런 방식으로 컴퓨터 계산 프로세스의 효율성을 최적화하는 것에 지나지 않는다는 것이다.
후자의 견해는 사용 가능한 기계가 고통스럽게 꽉 끼는 신발인 경우가 빈번한 상황에서 나오게 된 것으로, 그 시절에는 더 강력한 기계를 사용할 수 있게 되면 프로그래밍이 더는 문제가 되지 않을 것이라는 순진한 기대를 하기도 했다. 즉 우리가 기계를 그 한계까지 밀어붙여야 하는 분투가 더는 필요하지 않을 것이며, 바로 이게 프로그래밍의 전부이지 않은가? 그러나 그 후 몇십 년 동안 완전히 다른 일이 벌어졌다. 더 강력한 기계를 사용할 수 있게 되었지만, 그것도 단지 10^1배가 아니라 10^n배 더 강력해졌지만, 모든 프로그래밍 문제가 해결된 영원한 행복을 누리기는커녕 소프트웨어 위기에 빠져 허우적거리는 우리를 발견하게 된 것이다! 아니 도대체 왜?
가벼운 원인 하나는 현대 기계가 과거 기계보다 한 두 가지 점에서 기본적으로 더 다루기 어렵다는 데 있다. 첫째로 예측 및 재현이 불가능한 순간에 발생하는 I/O 인터럽트의 존재가 있다. 완전한 결정성 오토마톤(deterministic automaton)인 척하는 과거 순차 기계와 비교했을 때 이게 극적인 변화였으며, 이 기능으로 인해 생기는 로직 문제를 가볍게 보면 안 된다는 사실을 많은 시스템 프로그래머의 흰 머리가 증명하고 있다. 둘째로 멀티레벨 스토어를 장착한 기계가 관리 전략 문제를 불러왔는데, 이 주제에 대한 광범위한 문헌에도 불구하고 이게 다소 규정하기 어려운 문제로 남아 있다. 실제 기계의 구조적 변경으로 인해 추가된 복잡성에 대한 언급은 이쯤 해 두겠다.
내가 보기에 이는 사소한 원인이며 진짜 주요 원인은... 기계가 훨씬 더 강력해졌다는 점이다! 단순히 말하면 이렇다. 기계가 존재하지 않았을 때 프로그래밍은 전혀 문제가 되지 않았고, 약한 컴퓨터 몇 대가 생겼을 때 프로그래밍이 가벼운 문제가 되었으며, 이제 막강한 컴퓨터가 등장하자 프로그래밍도 똑같이 막대한 문제가 된 것이다. 이런 의미에서 보면 전자 산업계는 문제를 단 하나도 해결하지 못했고 도리어 만들어 내는 데 일조했다. 자신들 제품을 사용하는 데 있어서의 문제를 창조한 것이다. 사용 가능한 기계의 힘이 천 배 이상 증가함에 따라서 이 기계를 적용하려는 사회적 야망도 그에 비례하여 증가했으며, 불쌍한 프로그래머는 자신의 업무가 이 목적과 수단 사이 긴장이 폭발하는 분야에 놓여 있는 것을 발견하게 되었다. 하드웨어의 성능 향상과 더불어 훨씬 더 급격하게 개선된 그 신뢰성은 몇 년 전만 해도 프로그래머가 감히 꿈도 꾸지 못했던 솔루션을 가능하게 만들었다. 그리고 몇 년 지난 지금 프로그래머는 반드시 그것들을 꿈꾸어야 하고, 심지어 그러한 꿈을 현실로 바꿔야만 한다! 우리가 소프트웨어 위기에 처하게 된 것이 놀라운 일인가? 아니, 전혀 아니다. 심지어 이게 한참 전에 예측되기도 했다. 하지만 이름 없는 예언자들의 맹점은 그들이 옳았다는 것을 우리가 5년 뒤에야 비로소 알게 된다는 것이다.
그러다가 60년대 중반 끔찍한 일이 발생했다. 소위 말하는 제3세대 컴퓨터가 등장한 것이다. 공식 문서에 따르면 주요 설계 목표 중 하나가 가격/성능 비율이었다고 한다. 그러나 기계의 다양한 컴포넌트의 듀티 사이클을 "성능"으로 간주한다면, 꼭 필요한지 의심스러운 내부 관리 활동(internal housekeeping activities)으로 성능 목표의 대부분이 달성되는 설계를 막지 못할 것이다. 그리고 “가격”의 정의가 하드웨어에 지불하는 돈으로 결정된다면 지독히 프로그래밍하기 어려운 설계가 나오는 것을 막을 수 없다. 일례로 오더 코드가 프로그래머나 시스템에 조기 바인딩 결정(early binding decisions)을 강제하는 경우 해결할 수 없는 충돌이 발생한다. 그리고 이런 달갑지 않은 가능성의 많은 부분이 현실이 된 듯하였다.
이 기계가 발표되고 그 기능 사양이 알려졌을 때 많은 프로그래머가 상당히 우울했을 것이다. 적어도 나는 그랬다. 컴퓨팅 커뮤니티에 그러한 기계가 넘쳐날 것이 당연히 예상되었고, 이는 그 설계 견고성이 한층 더 중요해졌음을 의미했다. 하지만 설계가 그런 심각한 결점을 내포하고 있어서 컴퓨팅 과학의 발전이 한방에 최소 10년은 지연되었다고 느꼈고, 내 직업 생활 전체를 통틀어 가장 암울한 한 주를 보내게 되었다. 아마도 지금 가장 슬픈 사실은 그 모든 수년 간의 불만스러운 경험에도 불구하고 여전히 많은 사람이 기계는 원래 그런 식이어야 한다고 자연법칙처럼 믿고 있다는 것이다. 그들은 이 기계가 얼마나 많이 팔렸는지를 보면서 자신의 의심을 잠재우고, 저렇게 잘 팔리는데 설계가 그렇게까지 나쁠 리가 없다는 잘못된 안도감을 끌어낸다. 그러나 면밀히 살펴보면 이런 변호는 많은 사람이 담배를 피우므로 흡연이 건강에 나쁠 리가 없다는 주장과 동일한 설득력을 가진다.
이런 연유에서 우리가 과학 출판물 리뷰를 하듯이 컴퓨팅 분야 저널이 새로 발표되는 컴퓨터에 대한 리뷰를 게재하는 관례가 없는 점이 유감스럽다. 기계를 리뷰하는 것도 그만큼 중요한데 말이다. 개인적인 고백을 하자면 60년대 초 Communications 저널에 제출할 의도로 내가 그러한 리뷰를 썼던 적이 있다. 조언을 받기 위해 원고를 보냈던 몇몇 동료들은 출판을 권했지만 나는 감히 실행하지 못했다. 나 자신이나 저널 편집위원회가 맞닥뜨리게 될 어려움이 너무 거대할까 봐 두려웠기 때문이다. 이 부담감은 내 비겁함에서 나왔고, 나 자신을 점점 더 책망하는 일로 남았다. 내가 예견한 어려움은 일반적으로 인정되는 기준이 없다는 점에 있었다. 내가 적용하기로 선택한 기준의 타당성에 확신이 있었지만, 내 리뷰가 "개인 취향의 문제”라는 이유로 거부되거나 버려질까 봐 두려웠다. 나는 여전히 그러한 리뷰가 매우 유용하리라 생각하며, 그 등장을 고대하고 있다. 이것들의 등장이 받아들여진다는 것은 컴퓨팅 커뮤니티의 성숙함을 나타내는 확실한 신호이기 때문이다.
내가 하드웨어 쪽에 이렇게 관심을 기울이는 이유는 컴퓨팅 도구의 가장 중요한 측면 중 하나가 그 사용자들의 사고 습관에 미치는 영향이며, 이 영향력이 일반적으로 추정하는 것보다 몇 배 더 강하다고 믿을만한 이유가 있기 때문이다. 이제 우리 관심을 소프트웨어 쪽으로 전환해 보자.
이 분야는 너무 다양성이 커서 내가 몇 가지 선택으로 국한할 수밖에 없다. 내 이런 선택이 임의적이라는 것을 너무도 잘 알고 있으며, 여기 언급되지 않은 다른 노력들에 대한 나의 평가와 관련하여 어떠한 결론도 내리지 않기를 바란다.
초기에 영국 케임브리지의 EDSAC이 등장하였다. 이 기계의 설계와 사용 방식에 있어서 서브루틴 라이브러리 개념이 시작부터 핵심 역할을 한 것이 꽤 인상적이다. 거의 25년이 지난 지금 컴퓨팅 현장이 극적으로 변했지만, 기본 소프트웨어 개념이 여전히 우리와 함께하고 있고 폐쇄 서브루틴(closed subroutine) 개념도 여전히 프로그래밍의 핵심 개념 중 하나이다. 우리가 폐쇄 서브루틴을 최고의 소프트웨어 발명품 중 하나로 인정해야 한다. 이것이 컴퓨터의 세 개 세대를 거쳐 살아남았고, 추상화의 기본 패턴 중 하나를 구현할 수 있게 하므로 앞으로 몇 세대 더 살아남을 것이다. 안타깝게도 이것의 중요성이 3세대 컴퓨터 설계에서 과소평가되었으며, 산술연산 장치(arithmetic unit)의 명시적으로 명명된 레지스터 수가 많다는 것은 서브루틴 메커니즘의 큰 오버헤드를 의미한다. 하지만 이조차 서브루틴의 개념을 죽이지는 않았고, 다음 세대로 이런 형질이 유전되지 않기를 기도할 뿐이다.
내가 언급하고 싶은 소프트웨어 분야의 두 번째 주요 성장은 FORTRAN의 탄생이다. 그 당시에는 이것이 굉장히 대담한 프로젝트였고, 그 책임자들이 우리의 큰 존경을 받아 마땅하다. 10여 년간 광범위한 사용 후에야 비로소 보이기 시작한 결점들을 가지고 그들을 비난하는 것은 아주 불공평한 일이다. 10년의 성공적인 선견지명을 가질 수 있는 그룹은 정말 드물다! 돌이켜 보면 우리가 FORTRAN을 성공적인 코딩 기법으로 평가해야 한다. 다만 개념구상(conception)에 대한 효과적인 지원이 거의 없었으며, 이런 지원이 너무도 시급히 필요하다 보니 이 언어를 시대에 뒤떨어진 것으로 여기는 시간이 온 것이다. FORTRAN이 한 때 존재했다는 것을 더 빨리 잊을수록 더 좋다. 그것이 사고의 전달 수단으로 더는 적절하지 않기 때문이다. 이 언어는 우리의 지력(brainpower)을 낭비하고, 너무 리스크가 크고 사용하기에 비싸다. FORTRAN의 비극적 운명은 그것이 널리 받아들여진 데 있는데, 이게 무수히 많은 프로그래머를 우리의 과거 실수에 정신적으로 얽매이게 했다. 나는 더 많은 동료 프로그래머들이 호환성(compatibility)의 저주에서 스스로 자유로워지는 방법을 찾기를 매일 기도한다.
빠트리지 않고 싶은 세 번째 프로젝트는 LISP인데, 이게 완전히 다른 성격의 대단히 흥미로운 프로젝트이다. 몇 가지 아주 기본적인 원칙을 토대로 하는 LISP은 뛰어난 안정성(stability)을 보여 준다. 우리의 가장 정교한 컴퓨터 애플리케이션이라 할만한 것들의 상당수가 LISP으로 구현되었다. LISP을 묘사하면서 "컴퓨터를 오용하는 가장 지능적인 방법"이라는 농담을 하기도 한다. 나는 이게 대단한 찬사라고 생각하는데, 우리가 ‘자유의 맛’을 만끽하는 걸 나타내기 때문이다. 즉, 우리의 가장 재능 있는 동료 프로그래머들이 이전에는 불가능했던 생각을 생각해 내도록 하는데 이게 도움을 주었다.
내가 이야기 할 네 번째 프로젝트는 ALGOL 60이다. 현재까지도 FORTRAN 프로그래머는 특정 구현 측면에서 프로그래밍 언어를 이해하는 경향이 있고(따라서 8진법 덤프 또는 16진법 덤프가 만연함), LISP의 정의에는 언어가 무엇(what)을 의미하는지와 메커니즘이 어떻게(how) 작동하는지가 기묘하게 혼합되어 있다. 반면 유명한 “Report on the Algorithmic Language ALGOL 60(알고리즘 언어 AOGOL 60에 대한 완전한 정의 설명을 제공하는 16페이지짜리 정의서)”은 추상화를 한 단계 더 발전시키고 프로그래밍 언어를 구현에 독립적인 방식으로 정의하려는 진정한 노력의 결실이다. 이 보고서의 저자들이 이런 면에서 너무도 성공적이라 그게 실제 구현될 수 있는지에 대한 강한 의혹을 낳기도 했다! 이 보고서가 정형화 방법인 BNF(지금은 Backus-Naur-Form으로 많이 알려짐)의 힘을 훌륭하게 보여주었다. 즉 신중하게 기술된 영어 표현이 Peter Naur 같은 뛰어난 사람에 의해 사용되면 어떤 힘을 발휘하는지 보여주었다. 이만큼 짧은 문서 중에 컴퓨팅 커뮤니티에 이 정도로 심오한 영향을 미친 경우는 매우 드물다고 말해도 무방하다. 나중에는 관련성이 거의 없는 프로젝트에서도 간혹 그 후광을 빌리기 위해 비보호 상표인 ALGOL 또는 ALGOL 비슷한 이름을 쉽게 가져다 붙였는데, ALGOL의 명성에 대한 다소 망측한 찬사라 할 수 있다. 정의 기법으로써의 BNF의 강점은 언어의 약점을 보완하는 역할을 한다. 즉 지나치게 정교하고 그다지 체계적이지도 않은 신택스를 매우 적은 페이지 내로 빽빽이 쟁여 놓을 수 있게 한다. BNF만큼 강력한 표기법을 사용했다면 보고서 “Report on the Algorithmic Language ALGOL 60”의 길이가 훨씬 짧았을 것이다. ALGOL 60의 패러미터 메커니즘에 대해서는 내가 확신이 서지 않는다. 이것이 프로그래머에게 너무 많은 조합의 자유를 허용하며, 따라서 자신 있는 사용을 위해서는 프로그래머 측의 강력한 절제가 요구된다. 이게 구현 비용이 많이 드는 것 외에도 사용하기에 위험해 보인다.
마지막으로 달가운 주제는 아니지만 PL/I를 언급해야만 한다. 이 프로그래밍 언어의 정의서는 무시무시하게 길고 복잡하다. PL/I를 사용하는 것은 마치 조종실의 7,000개의 버튼, 스위치, 핸들을 조작해 가며 비행하는 것과 유사하다. 기본 도구인 프로그래밍 언어가 순전히 그 자체 기능만으로 이미 우리의 지적 통제를 벗어나는 상황에서 어떻게 점점 커지는 프로그램을 지적 지배력 내로 붙들고 있을 것인지 전혀 납득할 수 없다. PL/l가 그 사용자에게 미칠 수 있는 영향을 내가 설명해야 한다면 떠오르는 가장 가까운 비유가 약물이다. 상위 계층 프로그래밍 언어에 관한 한 심포지엄에서 자신을 열렬한 PL/I 사용자라고 했던 사람이 이 언어를 옹호하는 강의를 했던 것이 기억난다. PL/I를 칭찬하는 한 시간의 강의에서 그는 약 50개의 새로운 "기능(features)" 추가를 요청했으며, 이미 너무 많은 기능을 포함하고 있는 것이 그가 겪는 문제들의 주요 원인일 수 있다는 생각은 못 하는 듯했다. 그 발표자가 약물 중독의 모든 부정적 증상을 보였고, 오로지 더, 더, 더 많이 원할 수밖에 없는 정신적 침체 상태에 있었다. FORTRAN을 초기 질환 정도로 본다면 PL/I는 악성 종양의 증식 특징을 가진 치명적인 질병으로 판명할 수 있다.
과거 이야기는 이쯤 해 두자. 실수에서 배움을 얻지 못한다면 그게 헛된 일로 끝나버릴 것이다. 실제 우리가 아주 많은 것을 배웠고, 몇 년 내로 프로그래밍이 지금까지와는 대단히 다른 활동이 되어 있을 거라 생각한다. 너무도 달라져서 우리가 충격에 대비하는 편이 좋을 것이다. 내가 가능한 미래 중 하나를 그려보겠다. 언뜻 보기에는 가까운 미래에 등장할 수 있는 이 프로그래밍 비전이 완전히 터무니없게 느껴질지도 모르겠다. 따라서 내가 이 비전이 매우 현실적인 가능성이라는 결론에 이르게 할만한 고찰도 추가하겠다.
이 비전은 70년대가 끝나기 한참 전에 우리 프로그래밍 능력을 쥐어 짜내야 하는 종류의 시스템을 현재 비용(man-years)의 몇 %만 가지고도 설계 및 구현 할 수 있고 게다가 이 시스템이 버그가 거의 없을 것이라 말하고 있다. 이 두 가지 개선(비용과 품질)이 함께 나아간다. 보통 더 높은 품질은 더 높은 가격을 의미하기 때문에 후자의 관점에서 소프트웨어가 많은 다른 제품들과 차이를 보인다. 진정 신뢰할 수 있는 소프트웨어를 원하는 사람들은 버그 대부분을 애초부터 피할 수 있는 수단을 찾아야 하며 그 결과 프로그래밍 프로세스가 더 저렴해지는 것을 발견하게 될 것이다. 우리가 더 효과적인 프로그래머를 원한다면 그들이 디버깅에 시간을 낭비해서는 안 된다(애초에 버그를 도입하면 안 된다)는 것을 발견할 것이다. 다시 말해서 두 목표 모두 동일한 변화를 가리킨다.
이토록 짧은 기간에 그렇게 급격한 변화는 혁명으로 보아야 마땅하다. 사회적 문화적 관성이라는 불문 법칙을 들먹이며 가까운 과거 추세의 완만한 연장선으로 미래를 예상하는 사람들에게는 이 급격한 변화가 일어날 가능성이 무시할 정도로 낮아 보일 것이다. 하지만 우리 모두 알다시피 때때로 혁명이 일어난다! 그렇다면 이 혁명이 일어나 가능성은 어느 정도일까?
이게 실현되기 위해서는 세 가지 주요 조건이 반드시 충족되어야 한다. 첫째로 사회 전반에서 이 변화의 필요성을 인정해야 하고, 둘째로 그 경제적 필요성이 충분히 강력해야 하며, 셋째로 이 변화가 기술적으로 가능해야 한다. 내가 이 세 가지 조건을 순서대로 설명하겠다.
더 높은 신뢰성을 가진 소프트웨어 필요성의 인식과 관련해서는 더 이견이 없을 것으로 예상한다. 그러나 불과 몇 년 전만 해도 사정이 달랐으며, 소프트웨어 위기에 관해 이야기하는 것은 신성 모독처럼 여겨졌다. 전환점은 1968년 10월 Garmisch에서 열린 소프트웨어 공학 컨퍼런스였는데, 이 컨퍼런스가 소프트웨어 위기를 처음으로 공개적으로 인정하면서 센세이션을 일으켰다. 이제는 대규모 정교한 시스템의 설계가 매우 어려운 작업임을 일반적으로 인지하고 있고, 그러한 업무를 담당하는 사람들을 만나 보면 그들이 신뢰성 이슈에 대해 매우 우려한다는 것을 알 수 있다(그들이 마땅히 그래야 한다). 요컨대 우리의 첫 번째 조건이 충족된 것으로 보인다.
이제 경제적 필요성을 살펴보자. 요즘 들어 60년대 프로그래밍 직업이 보수를 너무 많이 받았고 앞으로는 프로그래머의 급여가 낮아질 것으로 예상된다는 의견이 자주 등장한다. 대개는 경기 침체와 관련하여 이런 의견이 나오지만, 이게 좀 다른 상당히 건전한 징후일 수 있다. 즉, 어쩌면 지난 10년간 프로그래머가 본인의 일을 해야 할 만큼 썩 잘 해내지 못했을지 모른다. 우리 사회가 프로그래머의 성과와 그들 제품의 성능에 불만을 느끼게 된 것이다. 하지만 이보다 훨씬 더 큰 영향력을 가지는 또 다른 요인이 있다. 현재는 특정 시스템의 소프트웨어 개발에 드는 비용이 그 하드웨어 구입 비용과 동일한 수준인 것이 보통이며, 우리 사회가 이를 그런대로 받아들이고 있다. 그러나 하드웨어 제조업자들은 향후 10년 내 하드웨어 가격이 10배씩 하락할 것으로 예상된다고 말한다. 만약 소프트웨어 개발이 지금처럼 서툴고 값비싼 프로세스를 계속한다면 상황이 완전히 균형을 잃게 될 것이다. 우리 사회가 이를 수용할 거라 기대할 수 없으며, 따라서 우리가 10배 더 효과적으로 프로그램하는 법을 배워야 한다. 바꿔 말하면 기계가 예산에서 가장 큰 항목을 차지하는 한 프로그래머가 어설픈 기술로도 빠져나갈 수 있었지만, 이 엄호 우산이 아주 빨리 접히게 될 것이다. 즉, 우리의 두 번째 조건 또한 충족된 것으로 보인다.
이제 세 번째 조건인 “기술적으로 가능한가?”에 대해 이야기해 보자. 나는 가능하다고 생각하며, 이를 뒷받침하는 여섯 가지 주장(argument)을 제시하겠다.
프로그램 구조에 대한 연구에 따르면 프로그램마다, 심지어 동일한 작업과 수학적 내용을 구현한 여러 대체 프로그램들도, 그 지적 관리용이성(intellectual manageability)이 크게 다를 수 있다고 한다. 다수의 관련 규칙이 발견되었으며, 이를 위반하면 프로그램의 지적 관리용이성이 심각하게 손상되거나 또는 완전히 파괴된다. 이러한 규칙들이 두 종류로 나뉜다. 첫 번째 종류의 규칙들은 기계적으로 쉽게 규제할 수 있는 것들이다. 즉 적절한 프로그래밍 언어 선택에 의해 규제가 가능하다. 예로는 goto 문 배제 또는 두 개 이상의 출력 패러미터를 가진 프로시저 배제를 들 수 있다. 두 번째 종류의 규칙들은 내가 보기에는 기계적으로 규제할 방법이 없다(어쩌면 내 능력이 부족해서 일지도 모르겠다). 이 규칙들은 일종의 자동 정리 증명기(automatic theorem prover)를 필요로 하는 것 같은데, 내가 그 존재 증거를 댈 수 없다. 따라서 두 번째 종류의 규칙들은 당분간, 그리고 아마도 영원히, 프로그래머가 준수해야 하는 규율로써 제시될 것 같다. 내가 염두에 두고 있는 이런 몇몇 규칙은 너무도 명백해서, 학습이 가능하고 주어진 프로그램이 이를 위반하는지 아닌지에 대한 논쟁도 전혀 필요 없다. 예를 들면 “루프를 그 종료에 대한 입증 없이 써서는 안 된다” 또는 “루프를 반복문 실행에 의해 파괴되지 않는 불변식 명시 없이 써서는 안 된다” 같은 요구들이다.
이제 우리 관심을 지적으로 관리용이한 프로그램의 설계 및 구현으로 한정할 것을 제안한다. 만약 누군가 이 제한이 너무 엄격해서 현실성이 없다고 우려한다면, 지적으로 관리용이한 프로그램 클래스가 알고리즘 적 솔루션이 가능한 많은 현실 문제 프로그램들을 충분히 포함할 수 있으니 안심하라고 말하고 싶다. 우리의 일은 프로그램을 만드는 것이 아니라 의도한 동작을 수행하는 컴퓨테이션 클래스들을 설계하는 것이라는 점을 잊지 말아야 한다. 우리 범위를 지적으로 관리용이한 프로그램으로 한정하자는 제안은 내가 예고했던 여섯 가지 주장 중 처음 두 개의 근거가 된다.
주장1은 프로그래머가 지적으로 관리용이한 프로그램만 고려하면 되기 때문에 그가 선택할 수 있는 여러 대안이 감당하기에 훨씬 더 쉽다는 것이다.
주장2는 우리 범위를 지적 관리용이한 프로그램의 부분집합으로 제한하기로 하면, 고려해야 할 솔루션 공간(solution space)을 대폭 축소할 수 있다는 것이다. 그리고 이 주장은 주장1과 구별된다.
주장3은 프로그램 정확성(correctness) 문제에 대한 건설적인 접근법에 기반한다. 프로그램을 만들고 이어서 그걸 테스트하는 것이 오늘날의 일반적인 기법이다. 프로그램 테스팅은 버그의 존재를 보여주는 매우 효과적인 방법이 될 수 있지만, 그 부재를 보여주는 데는 절망적으로 부적절하다. 프로그램의 신뢰 수준을 크게 높이는데 유일하게 효과적인 방법은 그 정확성에 대한 설득력 있는 증명(proof)을 제공하는 것이다. 그러나 먼저 프로그램을 만들고 이어서 그 정확성을 증명하는 방식은 바람직하지 않다. 증명을 제공해야 하는 요구가 불쌍한 프로그래머의 부담을 증가시킬 뿐이기 때문이다. 프로그래머는 정확성 증명과 프로그램을 함께 자라나게 해야 한다. 주장3은 기본적으로 다음의 관찰에 기반한다. 프로그래머는 먼저 설득력 있는 증명의 구조가 무엇인지 스스로 자문하고, 이를 발견하면 해당 증명의 요건을 충족하는 프로그램을 구축한다. 이때 이 정확성 요건은 매우 효과적인 휴리스틱 지침이 된다. 정의상 이런 접근법은 우리 범위를 지적으로 관리용이한 프로그램으로 제한하는 경우에만 적용 할 수 있으며, 여러 지적 관리용이한 프로그램 중에서 만족스러운 것을 찾을 수 있는 효과적인 수단을 우리에게 제공한다.
주장4는 프로그램을 설계하는데 필요한 지적 노력의 양이 프로그램 길이에 따라 달라지는 것과 관련이 있다. 전해지는 바로는 “필요한 지적 노력의 양이 프로그램 길이의 제곱에 따라 증가한다”라는 자연법칙이 있다고 한다. 하지만 고맙게도 아무도 이 법칙을 증명하지 못했는데, 그게 사실일 필요가 없기 때문이다. 우리가 모두 알다시피 아주 한정된 추론 한 조각으로 무수히 많은 경우를 포함할 수 있게 하는 유일한 정신적 도구가 "추상화(abstraction)"이다. 따라서 유능한 프로그래머의 가장 중요한 활동 중 하나로 추상화 능력의 효과적 활용을 들어야 한다. 추상화를 하는 목적이 대충 얼버무리는 데 있는 게 아니라 절대적 정확성을 제공하는 새로운 시맨틱 레벨을 생성하는 것임을 언급할 가치가 있다. 내가 우리의 추상화 메커니즘이 충분히 효과적이지 못하도록 막는 근본적 원인을 찾으려고 시도해 봤지만, 아무리 노력해도 그런 원인을 찾지 못했다. 그 결과 나는 “추상화 능력을 적절히 적용하면 프로그램을 구상하거나 이해하는데 필요한 지적 노력이 프로그램 길이에 비례하는 것보다 더 많이 증가할 필요가 없다”라는 가정을 지지하며, 지금까지 경험으로 봐도 이 가정이 틀리지 않았다. 한편 이 연구의 부산물이 훨씬 더 실질적인 의미가 있을 수 있는데, 실제로 그것이 내 주장4의 근거가 된다. 이 부산물이란 프로그램을 구축하는 전체 프로세스에서 중요한 역할을 하는 여러 추상화 패턴 식별을 말한다. 이 추상화 패턴들에 관한 충분한 연구가 있어서 각각에 대해 강의를 만들 수 있을 정도이다. 만약 추상화 패턴이 15년 전에 보편적인 상식이었다면 BNF에서 구문 지향 컴파일러(syntax-directed compliers)로 가는데 몇 년 대신에 몇 분이 걸렸을 수도 있다고 내가 깨달았을 때, 추상화 패턴에 대한 친숙함과 의식적 지식이 시사하는 바가 무엇인지 점점 분명해졌다. 따라서 지극히 중요한 추상화 패턴에 대한 우리의 최근 지식을 내가 네 번째 주장으로 제시한다.
이제 다섯 번째 주장에 대해 이야기 해 보자. 이 주장은 우리가 사용하는 도구가 우리 자신의 사고 습관에 미치는 영향과 관련이 있다. 내가 이 영향력을 무시하기 위해서, 그리고 인간 두뇌가 그 아티팩트(artifacts)의 최상의 자주적인 주인이라고 여기기 위해서, 십중팔구 르네상스에 그 뿌리를 두고 있는 문화적 전통을 관찰하였다. 그러나 내가 나 스스로나 동료들의 사고 습관을 분석하기 시작하면 좋든 싫든 완전히 다른 결론에 도달하게 된다. 즉, 우리가 이용하는 도구와 우리 생각을 표현 및 기록하는데 사용하는 언어/표기법이 우리가 생각하거나 표현할 수 있는 것을 결정짓는 주요 요인이라는 것이다! 프로그래밍 언어가 그 사용자의 사고 습관에 미치는 영향에 대한 분석, 그리고 지력이 단연코 우리의 가장 희귀한 자원이라는 인정, 이 두 가지가 다양한 프로그래밍 언어의 장점을 비교하는 새로운 척도를 제공한다. 유능한 프로그래머는 자신의 제한된 두개골 크기를 잘 알고 있으며, 따라서 아주 겸손하게 프로그래밍 작업에 접근한다. 특히 영리한 트릭을 마치 전염병인 것처럼 피한다. 내가 잘 알려진 한 대화형 프로그래밍 언어에 대해 들은 이야기인데, 프로그래밍 커뮤니티가 터미널을 갖추자마자 "원라이너(the one-liners)"라는 이름까지 붙은 특정 현상이 발생했다고 한다. 이 현상이 두 가지 유형을 보인다. 프로그래머가 자신의 한 줄짜리 프로그램을 다른 프로그래머에게 보이면서 이게 이러이러한 일을 하는 건데 더 적은 기호로 코딩할 수 있는지 묻거나(마치 그게 무슨 개념적 관련성이라도 있는 것처럼!), 또 다른 유형은 프로그램을 말없이 던져 주고 뭐 하는 건지 맞혀 보라고 하는 것이다. 이 사례는 도구로써의 언어가 영리한 트릭을 조장하는 구실이 되는 것을 보여주며, 그리고 바로 이 점이 자신이 얼마나 똑똑한지 보여주고 싶어 하는 사람들에게는 매력으로 작용할 것이다. 그러나 미안하게도 나는 이것이 프로그래밍 언어에 대해 말할 수 있는 가장 끔찍한 것 중 하나라고 생각한다. 우리가 가까운 과거로부터 배웠어야 하는 또 다른 교훈은 "더 풍부한” 또는 "더 강력한” 프로그래밍 언어의 개발이 실수라는 점이다. 바로크 양식의 거대한 덩어리, 별스러운 특질들이 모인 이 복합체는 기계적으로 그리고 정신적으로 관리가 불가능하다. 내 생각에는 매우 체계적이고 매우 간소한 프로그래밍 언어가 전망이 밝다. 내가 말하는 "간소하다"는 예를 들어 ALGOL 60의 ‘for 절’ 이나 심지어 FORTRAN의 ‘DO 루프’ 조차도 너무 바로크적이라고 내쫓길지 모르는 정도를 의미한다. 내가 아주 경험이 많은 프로그래머들과 작은 프로그래밍 실험을 한 적이 있는데, 의도하지 않은 전혀 예상 못 한 일이 나타났다. 실험 참여자 중 누구도 명백하고 가장 깔끔한 솔루션을 발견하지 못한 것이다. 면밀히 분석한 결과 공통된 원인이 밝혀졌다. 그들의 반복(repetition)에 대한 개념이 관련 제어 변수가 단계적으로 올라간다는 아이디어에 너무도 강하게 묶여 있다 보니, 아주 빤한 것도 보지 못하는 정신적 차단이 나타난 것이다. 그들의 솔루션은 효율성이 떨어지고, 불필요하게 이해하기 어려웠으며, 찾아내기까지 아주 오랜 시간이 걸렸다. 이게 흥미로운 사실을 드러내는 동시에 내게 충격을 던져준 경험이었다. 끝으로 내일의 프로그래밍 언어는 우리가 지금까지 사용하던 언어와 크게 다를 것이라 희망한다. 미래 언어는 복잡한 설계를 개념적으로 다루는데 필요한 모든 추상화가 작성된 구조에서 프로그래머가 사고하도록 지금까지보다 훨씬 더 많이 지원해야 한다. 다섯 번째 주장의 근거인 우리 미래 도구의 더 높은 적절성에 대한 이야기는 이쯤 해 두겠다.
덧붙여서 내가 프로그래밍 작업의 어려움을 현재 우리 도구의 부적절함 때문으로 생각하는 사람들에게 주의를 주고 싶은데, 그들이 우리 도구가 훨씬 더 적절해지면 프로그래밍이 더는 문제가 되지 않을 거라 결론 내릴 수 있기 때문이다. 프로그래밍은 여전히 매우 어려운 일로 남을 것이다. 우리가 상황적 번거로움에서 벗어나 자유로워졌다 해도 다음은 우리 프로그래밍 능력을 훨씬 뛰어넘는 문제와의 본격적인 씨름이 기다리고 있기 때문이다.
내 여섯 번째 주장은 이를 뒷받침하는 실험적 증거를 수집하기가 쉽지 않아서 반박이 있을 수 있지만, 그래도 그 타당성에 대한 내 믿음이 확고하다. 지금까지 내가 ‘계층형(hierarchy)’이라는 단어를 언급하지 않았는데, 이것이 잘 팩토링(유지 및 작업하기가 더 쉬운 여러 컴포넌트로 구성함)된 솔루션을 구현하는 모든 시스템의 핵심 개념이라고 보아도 무방하다. 내가 한 걸음 더 나아가 이와 관련된 한 가지 확고한 신념을 가질 수도 있다. 즉, “우리가 정말 만족스러운 방식으로 해결할 수 있는 유일한 문제들은 잘 팩토링 된 솔루션을 마침내 수용하는 문제들이다”라는 신념이다. 언뜻 보기에 이런 인간 한계에 대한 관점이 우리의 곤경을 나타내는 다소 우울한 견해로 느껴질지 모르지만, 나는 그렇게 생각하지 않는다. 오히려 우리 한계와 함께 사는 법을 배우는 가장 좋은 방법은 그것을 제대로 아는 것이다. 우리가 오로지 팩토링된 솔루션만 시도할 정도로 충분히 겸손해졌을 때쯤에는(그 외 노력은 우리의 지적 통제를 벗어나기 때문에), 시스템을 유용하게 팩토링하는 우리 능력을 훼손하는 모든 인터페이스를 최선을 다해 피할 것이다. 그리고 이런 노력은 처음에 다루기 어려웠던 문제(효율적인 알고리즘 솔루션이 없는 문제)도 결국 팩토링이 가능해지는 결과로 반복적으로 이어지게 할 것이다. "코드 생성"이라 불리는 컴파일 단계에서 생기는 문제 대부분이 오더 코드의 기묘한 속성 때문에 발생함을 목격한 사람이라면 내가 염두에 두고 있는 종류의 간단한 예를 떠올릴 수 있을 것이다. 잘 팩토링 된 솔루션의 더 광범위한 적용 가능성이 향후 10년간 일어날 수 있는 혁명의 기술적 실현 가능성에 대한 내 여섯 번째이자 마지막 주장이다.
다른 사람에게 내 믿음을 강요할 수 없다는 것을 잘 알고 있기 때문에 내 고찰을 얼마나 무게감 있게 받아들일지는 여러분 스스로 결정하도록 맡기겠다. 중대한 혁명이 일어나면 매번 그랬듯이 이것도 격렬한 반대를 불러일으킬 수 있으며, 그러한 발전을 방해하는 보수 세력이 누구일지 우리가 자문 해 볼 수 있다. 나는 대기업이나 심지어 컴퓨터 사업 분야에서 그런 세력이 나올 거라 예상하지 않는다. 오히려 오늘날의 교육훈련을 제공하는 교육 기관이나 자신들의 과거 프로그램이 너무도 중요해서 이를 재작성하고 개선할 필요가 없다고 생각하는 보수적인 컴퓨터 사용자 그룹에서 반대가 나오리라 예상한다. 슬프게도 많은 대학 캠퍼스에서 중앙 컴퓨팅 시설의 선택이 몇몇 저명하고 값비싼 애플리케이션의 요구에 따라 결정되어 버리고, 이 선택으로 인해 얼마나 많은 "소규모 사용자"가 그들의 프로그램을 작성하는 데 있어 어려움을 겪게 될 것인지의 문제는 무시되는 게 현실이다. 예를 들면, 고에너지 물리학이 미지불된 실험 기자재 가격으로 과학계를 갈취하는 것 같은 일이 너무 자주 있다. 물론 가장 쉬운 답은 기술적 타당성을 딱 잘라 부인하는 것이지만, 유감스럽게도 그러려면 상당히 강력한 논증을 제시할 필요가 있다. 오늘날의 평균 프로그래머의 지적 상한선이 이 혁명이 일어나는 것을 막을 것이라는 발언에서 안도감을 얻는 것도 불가능하다. 다른 사람들이 훨씬 더 효과적으로 프로그래밍하면 그러지 못한 사람은 그림 밖으로 차차 밀려날 수밖에 없다.
정치적인 방해 또한 있을 수 있다. 내일의 전문 프로그래머를 우리가 어떻게 교육해야 할지 알고 있다 하더라도 우리가 사는 사회에서 그걸 허용할지는 확실하지 않다. 단순히 지식을 전파하는 대신 방법론을 가르치는 것의 첫 번째 효과는 이미 능력 있는 사람의 능력을 더욱 높여서 결과적으로 인텔리전스 차이를 확대하는 것이다. 교육 시스템이 균질화된 문화를 확립하기 위한 도구로 사용되는 사회, 즉 크림이 정상에 떠오르는 것을 막는 사회에서는 유능한 프로그래머 교육이 정치적으로 구미에 맞지 않을 수도 있다.
이제 마무리를 하겠다. 자동 컴퓨터가 우리와 함께 한 지 25년이 되었다. 컴퓨터가 도구로써 우리 사회에 큰 영향을 미쳤지만, 그런 측면에서 컴퓨터의 영향력은 우리 문화 표면을 스치는 잔물결에 불과하다. 이에 비해 지적 도전 매체로써의 컴퓨터는 인류 문화사에 전례가 없을 정도의 훨씬 더 심오한 영향을 미칠 것이다. 계층형 시스템은 한 레벨에서 하나의 분할되지 않은 엔터티로 간주하던 것을 더 자세한 다음 하위 레벨에서는 복합 오브젝트로 간주하는 속성을 지닌다. 즉, 각 레벨에서 적용되는 자연적인 공간 단위 또는 시간 단위가 한 레벨에서 다음 하위 레벨로 우리 관심을 옮길 때마다 한 단계씩 감소한다. 우리가 벽을 벽돌 관점에서 이해하고, 벽돌은 결정으로 이해하고, 결정은 분자로 이해하는 것과 비슷하다. 결과적으로 계층형 시스템에서 의미 있게 구별하는 레벨 수는 가장 큰 단위와 가장 작은 단위 간 비율 로그에 비례하며, 이 비율이 매우 크지 않는 한 레벨의 수가 크지 않다. 컴퓨터 프로그래밍에서 기본 빌딩 블록의 시간 단위가 1마이크로초 미만이지만, 우리 프로그램의 계산 시간은 몇 시간이 걸릴 수도 있다. 내가 10^10 또는 그 이상의 비율을 커버하는 다른 기술의 존재를 알지 못한다. 컴퓨터는 그 환상적인 속도 덕분에 고도의 계층적인 아티팩트가 가능하고 또한 필수적인 환경을 제공하는 최초의 기술인 것 같다. 이 도전(즉 프로그래밍 작업과의 대결)이 너무도 특별해서, 이 새로운 경험이 우리 자신에 대해 많은 것을 가르쳐 줄 수 있다. 이것이 설계 및 구축 프로세스에 대한 우리의 이해를 심화해야 하고, 우리 생각을 정리하는 일에 대한 더 나은 통제를 가해야 한다. 이게 그렇게 하지 않는다면, 내 기준에 우리가 컴퓨터를 쓸 자격이 전혀 없다!
이 도전이 이미 우리에게 몇 가지 교훈을 주었으며, 내가 이 강연에서 강조하고자 선택한 교훈은 다음과 같다. 우리가 프로그래밍 작업의 엄청난 어려움을 충분히 인식하고 접근한다면, 그리고 수수하고 명쾌한 프로그래밍 언어를 고수한다면, 그리고 인간 머리의 본질적인 한계를 인정하고 매우 겸손한 프로그래머의 자세로 접근한다면, 비로소 훨씬 더 나은 프로그래밍을 할 수 있게 될 것이다.
'테스팅 관리 및 통제 > 테스팅 교육훈련' 카테고리의 다른 글
2021년 소프트웨어 테스팅 동향: 2021년 배워야 할 15가지 기술 by softwaretestingportal.com (0) | 2022.01.31 |
---|---|
해외 소프트웨어 테스팅 무료 온라인 강의 소개 – Channel 9 (0) | 2021.07.13 |
해외 소프트웨어 테스팅 무료 온라인 강의 소개 – TAU (1) | 2021.07.06 |
해외 소프트웨어 테스팅 무료 온라인 강의 소개 – MIT (0) | 2021.06.29 |
국내 소프트웨어 테스팅 무료 온라인 강의 소개 – KOCW (0) | 2021.06.25 |