이론 구축으로서의 프로그래밍

피터 나우르, 1985년

서론

이 글은 프로그래밍이란 무엇인지 이해하는 데 기여하려는 시도이다. 여기서는 프로그래밍을, 프로그래머가 자신이 다루는 대상에 관해 특정한 종류의 통찰, 즉 하나의 이론을 형성하거나 획득하는 활동으로 보아야 한다고 제안한다. 이러한 제안은 프로그래밍을 프로그램과 그 밖의 몇 가지 텍스트를 생산하는 일로 보아야 한다는, 보다 일반적인 듯한 관념과 대조된다.

여기서 제시하는 견해의 배경에는 프로그램과 그것을 다루는 프로그래머 팀에 실제로 어떤 일이 일어나는지를 관찰한 경험이 있다. 특히 예상하지 못했거나 잘못된 프로그램 실행 또는 반응이 발생한 상황과 프로그램을 수정하는 과정에서 나타나는 현상들이 중요하다. 프로그래밍을 생산 활동으로 보는 관점으로는 이러한 현상들을 제대로 설명하기 어렵다는 사실은, 그 관점이 우리를 오도하고 있음을 시사한다. 이에 대한 대안으로 이론 구축 관점을 제시하고자 한다.

이 글의 보다 일반적인 배경에는 프로그래밍이 무엇인지 적절하게 이해하는 일이 중요하다는 확신이 있다. 우리가 프로그래밍을 부적절하게 이해한다면, 그 활동에서 발생하는 어려움 역시 잘못 이해하게 될 것이며, 그러한 어려움을 극복하려는 시도는 갈등과 좌절을 낳게 될 것이다.

이 글에서는 먼저 논의의 토대가 되는 몇 가지 중요한 경험을 개괄한다. 이어서 프로그래밍이 무엇인지에 관한 하나의 이론, 즉 이론 구축 관점을 설명한다. 그다음 절들에서는 이론 구축 관점으로부터 따라오는 여러 결과를 살펴본다.

프로그래밍과 프로그래머의 지식

여기서 나는 프로그래밍이라는 말을, 프로그램을 이용한 해결책을 설계하고 구현하는 모든 활동을 가리키는 뜻으로 사용하겠다. 내가 관심을 두는 것은 현실 세계의 어떤 활동에서 중요한 부분과 측면을 골라, 컴퓨터에서 실행되는 프로그램이 수행할 수 있는 형식적 기호 조작과 대응시키는 활동이다. 이렇게 이해한다면, 내가 말하는 프로그래밍 활동에는 프로그램 실행이 대응하고 있는 현실 세계의 활동이 변화함에 따라 프로그램도 시간에 따라 발전하는 과정, 다시 말해 프로그램의 수정이 당연히 포함되어야 한다.

내가 주장하려는 핵심을 한 가지 방식으로 표현하면 다음과 같다. 이러한 의미에서의 프로그래밍은 무엇보다도 프로그래머가 특정한 종류의 지식을 쌓아가는 활동이어야 한다. 이 지식은 기본적으로 프로그래머가 직접 소유하는 것이며, 문서는 이를 보조하는 부차적인 산물이다.

이어지는 절에서 이 견해를 더 자세히 설명하기에 앞서, 이 절의 나머지 부분에서는 대규모 프로그램을 다루면서 겪은 실제 경험 중 내가 그 문제들을 숙고할수록 점점 더 중요하게 느끼게 된 몇 가지를 소개하겠다. 각각의 사례는 내가 직접 경험했거나, 해당 활동을 직접 수행한 사람들로부터 전해 들은 것이다.

사례 1은 컴파일러에 관한 것이다. A 그룹은 언어 L을 위한 컴파일러를 개발했고, 이 컴파일러는 컴퓨터 X에서 매우 잘 작동했다. 이후 B 그룹이 L을 소폭 확장한 언어 L+M을 위한 컴파일러를 컴퓨터 Y에서 작성하는 임무를 맡게 되었다. B 그룹은 A 그룹이 개발한 L용 컴파일러를 설계의 좋은 출발점으로 삼기로 했다. 이들은 A 그룹과 협력 관계를 맺고, 주석이 달린 프로그램 텍스트와 상세한 설계 논의를 포함한 완전한 문서뿐 아니라 직접적인 조언도 제공받았다.

이 협력은 효과적이었으며, B 그룹은 자신들이 원하던 컴파일러를 개발할 수 있었다. 여기서 중요한 점은 언어 확장 M을 어떻게 구현할 것인가에 관해 A 그룹이 제공한 직접적인 조언의 중요성이다. 설계 단계에서 B 그룹은 확장 기능을 수용하는 방법을 제안하고 A 그룹에 검토를 요청했다. 몇 가지 중요한 사례에서, B 그룹이 제안한 해결책은 기존 컴파일러의 구조에 내재해 있을 뿐 아니라 문서에서도 장황하게 설명되어 있던 기능을 전혀 활용하지 않고 있다는 사실이 드러났다. 대신 B 그룹은 기존 구조에 패치를 덧붙이는 방식을 제안했는데, 이는 기존 구조가 지닌 힘과 단순성을 사실상 파괴하는 것이었다.

A 그룹의 구성원들은 이러한 문제를 즉시 알아차렸으며, 기존 구조의 틀 안에서 완전히 설명할 수 있는 단순하고 효과적인 해결책을 제시할 수 있었다. 이는 완전한 프로그램 텍스트와 추가 문서만으로는, 매우 적극적으로 배우려 했던 B 그룹에게조차 설계에 관한 더 깊은 통찰, 즉 A 그룹 구성원들이 직접 가지고 있던 이론을 전달하기에 충분하지 않았음을 보여주는 사례이다.

그 후 몇 년 동안 B 그룹이 개발한 컴파일러는 같은 조직의 다른 프로그래머들에게 인계되었으며, 이때는 A 그룹의 지도가 제공되지 않았다. 약 10년 동안 추가 수정이 이루어진 뒤, A 그룹의 한 구성원이 그 컴파일러에 관해 입수한 정보에 따르면 원래의 강력한 구조는 여전히 알아볼 수 있었지만, 온갖 종류의 무정형적인 추가 사항들로 인해 완전히 무력화되어 있었다. 이 사례에서도 프로그램 텍스트와 문서는 가장 중요한 설계 아이디어 중 일부를 전달하는 매체로서 충분하지 않았음이 드러났다.

사례 2는 산업 생산 활동을 감시하는 대규모 실시간 시스템의 설치와 결함 진단에 관한 것이다. 이 시스템은 제작사에 의해 판매되며, 각 시스템은 설치 장소의 센서와 표시 장치라는 구체적인 환경에 맞추어 개별적으로 조정된다. 각 설치에 제공되는 프로그램의 크기는 약 20만 줄 정도이다.

이러한 시스템을 다루는 방식에서 중요한 경험은 설치 및 결함 진단 프로그래머 그룹의 역할과 작업 방식에 관한 것이다. 첫째, 이 프로그래머들은 시스템이 설계되던 시점부터 수년 동안 전업으로 시스템과 긴밀하게 관련되어 있었다. 둘째, 이들은 결함을 진단할 때 거의 전적으로 자신들이 즉시 떠올릴 수 있는 시스템 지식과 주석이 달린 프로그램 텍스트에 의존했으며, 자신들에게 도움이 될 만한 추가 문서가 어떤 형태일지 상상조차 하지 못했다. 셋째, 특정 설치 시스템의 운영을 담당하는 다른 프로그래머 그룹들은 제작사로부터 시스템 문서와 사용법에 관한 충분한 지도를 받았지만, 반복적으로 어려움을 겪었다. 이들이 제작사의 설치 및 결함 진단 프로그래머에게 문의하면, 문제의 원인은 기존 문서를 충분히 이해하지 못한 데 있는 것으로 밝혀졌으며, 설치 및 결함 진단 프로그래머들은 그 문제를 쉽게 해결할 수 있었다.

적어도 일부 대규모 프로그램의 경우, 프로그램을 지속적으로 조정하고 수정하며 오류를 고치는 일은 그 프로그램과 긴밀하고 지속적인 관계를 유지해 온 프로그래머 그룹이 보유한 특정한 종류의 지식에 본질적으로 의존한다는 결론을 피하기는 어려워 보인다.

라일의 이론 개념

프로그래밍의 핵심적인 부분에 프로그래머의 지식 형성이 포함되어야 한다는 점을 인정한다면, 다음 문제는 그 지식의 성격을 더 정확히 규정하는 것이다. 여기서 검토할 제안은 프로그래머의 지식을 라일이 말하는 의미에서 하나의 이론으로 보아야 한다는 것이다.

간단히 말해, 이러한 의미에서 이론을 가지고 있는 사람은 어떤 일을 어떻게 해야 하는지 알고 있을 뿐 아니라, 그 일을 실제로 수행하면서 해당 활동에 관해 설명하고 정당화하며 질문에 답할 수 있다. 라일의 이론 개념은 K. 포퍼가 ‘비체현된 세계 3의 대상’이라고 부르는 것의 한 예로 볼 수 있으며, 따라서 철학적으로도 옹호할 만한 지위를 가진다는 점을 덧붙일 수 있다. 이 절에서는 라일의 이론 개념을 더 자세히 설명하겠다.

라일은 지적 활동의 본질, 특히 지적 활동이 단순히 지능적인 활동과 어떻게 다르며 어떻게 그것을 넘어서는지를 분석하는 과정에서 이론이라는 개념을 발전시킨다.

지능적인 행동에서 사람은 어떤 특정한 사실에 관한 지식을 드러내는 것이 아니라, 농담을 만들고 이해하거나, 문법에 맞게 말하거나, 낚시를 하는 것처럼 특정한 일을 할 수 있는 능력을 드러낸다. 좀 더 구체적으로 말하면, 지능적인 수행은 일정한 기준에 따라 일을 잘 해낸다는 점에서 특징지어질 뿐 아니라, 그 기준을 적용해 실수를 발견하고 교정하며, 다른 사람의 사례로부터 배우는 등의 능력도 보여준다.

여기서 지능이라는 개념은 지능적인 행동이 규칙이나 지침, 방법을 따르는 데 의존한다는 생각에 기반하지 않는다는 점에 주목할 필요가 있다. 오히려 규칙을 따르는 행위 자체도 더 지능적으로 또는 덜 지능적으로 수행될 수 있다. 지능의 발휘가 규칙을 따르는 데 의존한다면, 규칙을 따르는 방법에 관한 규칙이 필요하고, 다시 그 규칙을 따르는 방법에 관한 규칙이 필요해지는 식으로 무한히 후퇴하게 된다. 이는 명백히 불합리하다.

단순히 지능적인 활동을 넘어 지적 활동을 특징짓는 것은 사람이 이론을 구축하고 소유한다는 점이다. 여기서 이론이란, 어떤 일을 지능적으로 수행할 수 있을 뿐 아니라 그것을 설명하고, 그것에 관한 질문에 답하고, 그것을 두고 논증하는 등의 활동을 하기 위해 사람이 가지고 있어야 하는 지식을 의미한다. 이론을 가진 사람은 이러한 활동에 참여할 준비가 되어 있으며, 이론을 구축하고 있는 사람은 그러한 상태에 도달하려고 노력하고 있는 것이다.

여기서 사용하는 이론이라는 개념은 전문적인 탐구 분야에서 만들어지는 정교한 구성물에만 적용되는 것이 아니다. 교육받은 사람이라면 누구나 특정한 상황에서 참여하게 되는 활동에도 동일하게 적용된다. 가구를 어떻게 배치할지 계획하거나 특정한 교통수단을 이용해 어떤 장소로 가는 방법을 계획하는 것처럼, 일상생활의 대단하지 않은 활동조차 사람들로 하여금 이론을 세우게 할 수 있다.

여기서 사용하는 이론 개념은 통찰의 가장 일반적이거나 추상적인 부분에만 명시적으로 한정되지 않는다. 예를 들어 여기서 말하는 의미로 뉴턴의 역학 이론을 가지고 있으려면, 힘은 질량과 가속도의 곱이라는 중심 법칙을 이해하는 것만으로는 충분하지 않다.

쿤이 더 자세히 설명한 것처럼, 이론을 가진 사람은 중심 법칙이 현실의 특정한 측면에 어떻게 적용되는지를 이해해야 한다. 그래야만 다른 유사한 측면을 알아보고 그 이론을 적용할 수 있다. 따라서 뉴턴의 역학 이론을 가진 사람은 그것이 진자와 행성의 운동에 어떻게 적용되는지 이해해야 하며, 세계에서 이와 유사한 현상을 알아봄으로써 수학적으로 표현된 이론의 규칙을 적절하게 사용할 수 있어야 한다.

이론이 현실 세계의 상황과 사건들 사이에서 특정한 종류의 유사성을 파악하는 능력에 의존한다는 사실은, 이론을 가진 사람이 보유한 지식이 원칙적으로 규칙의 형태로 표현될 수 없는 이유를 설명해 준다. 문제의 유사성은 기준의 형태로 표현되지 않으며, 표현될 수도 없다. 이는 사람의 얼굴, 선율, 와인의 맛과 같은 수많은 다른 종류의 대상들 사이의 유사성이 기준으로 표현될 수 없는 것과 마찬가지이다.

프로그래머가 구축해야 하는 이론

라일의 이론 개념에 따라 말하면, 프로그래머가 구축해야 하는 것은 현실 세계의 특정한 일들이 컴퓨터 프로그램에 의해 어떻게 처리되거나 지원될 것인지에 관한 이론이다. 프로그래밍의 이론 구축 관점에서는 프로그래머가 구축한 이론이 프로그램 텍스트, 사용자 문서, 명세와 같은 추가 문서 등의 다른 산물보다 우선한다.

이론 구축 관점을 주장하기 위해서는, 프로그래머가 이론을 가지고 있기 때문에 소유하게 되는 지식이 문서화된 산물에 기록된 내용을 필연적이고 본질적인 방식으로 넘어선다는 점을 보여주는 것이 기본적인 과제이다. 이에 대한 답은 프로그래머의 지식이 적어도 다음 세 가지 핵심 영역에서 문서에 담긴 지식을 넘어선다는 것이다.

1

프로그램의 이론을 가진 프로그래머는 그 해결책이 자신이 처리하도록 돕는 현실 세계의 일들과 어떻게 관련되는지를 설명할 수 있다.

이러한 설명은 현실 세계의 일들이 전체적인 특성과 세부 사항 모두에서 어떤 의미로 프로그램 텍스트와 추가 문서에 대응되는지를 다루어야 한다. 따라서 프로그래머는 프로그램 텍스트의 각 부분과 전체적인 구조적 특성 각각이 현실 세계의 어떤 측면 또는 활동에 대응하는지를 설명할 수 있어야 한다.

반대로 현실 세계의 어떤 측면이나 활동에 대해서도 그것이 프로그램 텍스트에 어떻게 대응되는지를 말할 수 있어야 한다. 물론 현실 세계의 측면과 활동 중 압도적으로 많은 부분은 해당 문맥에서 무관하기 때문에 프로그램 텍스트의 범위 밖에 놓인다. 그러나 현실 세계의 어떤 부분이 관련이 있다고 결정하는 일은 현실 세계 전체를 이해하는 사람만이 할 수 있다. 이러한 이해는 프로그래머가 제공해야 한다.

2

프로그램의 이론을 가진 프로그래머는 프로그램의 각 부분이 현재와 같은 형태를 취하고 있는지를 설명할 수 있다. 다시 말해 실제 프로그램 텍스트를 일종의 정당화로 뒷받침할 수 있다.

그 정당화의 최종적인 근거는 언제나 프로그래머가 직접 가지고 있는 직관적인 지식이나 판단이어야 하며, 끝까지 그러한 상태로 남는다. 설계 규칙의 적용, 정량적인 추정, 대안과의 비교 등을 포함하는 추론을 이용해 정당화하는 경우에도 마찬가지이다. 어떤 원칙과 규칙을 선택할지, 그리고 그러한 원칙과 규칙이 현재 상황에 적절한지를 판단하는 일은 궁극적으로 프로그래머의 직접적인 지식에 의존할 수밖에 없기 때문이다.

3

프로그램의 이론을 가진 프로그래머는 현실 세계의 일들을 새로운 방식으로 지원하기 위해 프로그램을 수정해 달라는 어떤 요구에도 건설적으로 대응할 수 있다.

기존 프로그램에 수정 사항을 가장 적절하게 통합하는 방법을 설계하는 일은 새로운 요구 사항과 프로그램에 이미 구축되어 있는 작동 기능 사이의 유사성을 인식하는 데 의존한다. 이때 인식해야 할 유사성은 현실 세계의 여러 측면 사이의 유사성이다. 이러한 유사성은 현실 세계에 관한 지식을 가진 행위자, 즉 프로그래머에게만 의미가 있으며, 앞서 프로그램에 대한 정당화를 유한한 기준이나 규칙의 집합으로 환원할 수 없다고 설명한 것과 같은 이유로 그러한 기준이나 규칙으로 환원될 수 없다.

이 절의 논의는 프로그래밍에 관한 이론 구축 관점을 채택해야 하는 몇 가지 기본적인 논거를 제시한다. 그러나 이 관점을 평가하려면 이 관점이 프로그래밍과 그 문제들을 일관성 있게 이해하는 데 어느 정도 기여할 수 있는지를 고려해야 한다. 이러한 문제들은 다음 절들에서 논의한다.

프로그램 수정의 문제와 비용

프로그래밍에 관한 이론 구축 관점을 제안하는 중요한 이유 중 하나는 프로그램 수정을 건전하게 이해할 수 있는 통찰을 확립하려는 데 있다. 따라서 가장 먼저 프로그램 수정의 문제를 분석하겠다.

소프트웨어는 수정될 것이라는 점에 대해서는 모두가 동의하는 듯하다. 프로그램은 일단 운영되기 시작하면 당면한 문제에 대한 해답의 일부에 지나지 않는 것으로 여겨지는 경우가 언제나 발생한다. 또한 프로그램을 실제로 사용하는 과정 자체가 프로그램이 제공하면 유용할 추가 서비스에 관한 아이디어를 만들어 낸다. 따라서 수정 사항을 처리할 방법이 필요하다.

프로그램 수정의 문제는 프로그래밍 비용의 문제와 밀접하게 연결되어 있다. 프로그램의 작동 방식을 바꿀 필요가 있을 때, 완전히 새로운 프로그램을 작성하는 대신 기존 프로그램 텍스트를 수정함으로써 비용을 절감하기를 기대하게 된다.

프로그램을 낮은 비용으로 수정할 수 있어야 한다는 기대는 좀 더 면밀한 분석을 요구한다. 첫째, 이러한 기대는 인간이 만든 다른 복잡한 구조물의 수정과 비유한다고 해서 뒷받침되지 않는다. 예를 들어 건축물처럼 수정 작업이 종종 이루어지는 경우, 수정에는 많은 비용이 든다는 사실이 잘 알려져 있다. 실제로 기존 건물을 완전히 철거한 뒤 새로 건축하는 편이 경제적으로 더 낫다고 판단되는 경우가 많다.

둘째, 프로그램 수정이 낮은 비용으로 가능하다는 기대는 프로그램이 쉽게 편집할 수 있는 매체에 저장된 텍스트라는 사실에 의해 뒷받침되는 것처럼 보일 수 있다. 그러나 이러한 근거가 타당하려면 지배적인 비용이 텍스트 조작에 들어가는 비용이라고 가정해야 한다. 이는 프로그래밍을 텍스트 생산으로 보는 관념과 일치할 것이다.

그러나 이론 구축 관점에서는 이러한 논증 전체가 잘못된 것이다. 이 관점은 일반적으로 프로그램을 낮은 비용으로 수정할 수 있으리라는 기대를 전혀 뒷받침하지 않는다.

이와 밀접하게 관련된 또 다른 문제는 프로그램의 유연성이다. 프로그램에 유연성을 포함한다는 것은 당장은 요구되지 않지만 앞으로 유용해질 가능성이 있는 특정한 작동 기능을 미리 프로그램 안에 구축하는 것이다. 따라서 유연한 프로그램은 외부 환경에서 발생하는 특정 부류의 변화를 프로그램 자체를 수정하지 않고도 처리할 수 있다.

변화하는 환경에 쉽게 적응할 수 있도록 프로그램을 높은 유연성을 갖추어 설계해야 한다는 주장이 흔히 제기된다. 쉽게 달성할 수 있는 유연성에 관한 한 이러한 조언은 합리적일 수 있다. 그러나 일반적으로 유연성을 확보하려면 상당한 비용이 든다.

유연성의 각 항목마다 어떤 상황을 포괄해야 하는지, 어떤 매개변수로 제어해야 하는지 등을 설계해야 한다. 그런 다음 그것을 구현하고, 시험하고, 설명해야 한다. 이 비용은 전적으로 미래의 사건에 따라 유용성이 결정되는 프로그램 기능을 확보하기 위해 지출된다. 따라서 프로그램에 미리 내장된 유연성이 변화하는 현실 세계의 환경에 프로그램을 적응시켜야 한다는 일반적인 요구에 대한 해답이 될 수 없다는 것은 명백하다.

프로그램 수정에서는 현실 세계에서 프로그램이 대응해야 하는 활동의 변화에 맞추어 기존의 프로그램화된 해결책을 변경해야 한다. 수정에서 무엇보다 먼저 필요한 것은 기존 해결책과 원하는 수정 사항이 요구하는 조건을 서로 대면시키는 일이다.

이 대면 과정에서는 기존 해결책의 능력과 새로운 요구 사항 사이에 어느 정도의 유사성이 있으며, 그것이 어떤 종류의 유사성인지를 판단해야 한다. 유사성을 판단해야 한다는 필요성에서 이론 구축 관점의 장점이 드러난다.

적절한 통찰을 가진 사람이 직접 참여해야 한다는 핵심적인 요구를 무시하는 프로그래밍 관점의 한계는 바로 유사성을 판단하는 과정에서 분명하게 드러난다. 여기서 인식해야 하는 종류의 유사성은 프로그램의 이론을 가진 인간에게는 접근 가능하지만, 규칙을 통해 판단할 수 있는 범위에서는 완전히 벗어나 있다. 그러한 유사성을 판단하는 기준 자체를 공식화할 수 없기 때문이다.

프로그래머는 새로운 요구 사항과 프로그램이 이미 충족하고 있는 요구 사항 사이의 유사성에 관한 통찰을 바탕으로, 수정 사항을 구현하기 위해 프로그램 텍스트를 어떻게 변경해야 하는지를 설계할 수 있다.

어떤 의미에서는 이론의 수정이라는 것은 있을 수 없고, 프로그램의 수정만 있을 수 있다. 이론을 가진 사람이라면 프로그램 수정으로 이어질 수 있는 종류의 질문과 요구에 이미 대응할 준비가 되어 있어야 하기 때문이다.

이러한 관찰로부터 중요한 결론이 도출된다. 프로그램 수정의 문제는 프로그래밍을 이론 구축 활동으로 인식하지 않고, 프로그램 텍스트를 생산하는 일이라고 가정하는 데서 발생한다.

이론 구축 관점에 따르면, 기반 이론을 제대로 이해하지 못한 프로그래머들이 수정 작업을 함으로써 프로그램 텍스트가 쇠퇴하는 현상을 이해할 수 있다. 실제로 프로그램 텍스트와 프로그램 실행의 외부적인 동작만을 변경하는 일로 본다면, 주어진 수정 요구 사항은 대개 여러 가지 서로 다른 방식으로 구현할 수 있으며, 그 방식들은 모두 올바르게 작동할 수 있다.

그러나 프로그램의 이론과 관련하여 바라보면 이러한 방식들은 매우 다르게 보일 수 있다. 일부는 이론에 부합하거나 이론을 자연스럽게 확장하는 반면, 다른 일부는 그 이론과 완전히 모순되며, 프로그램의 주요 부분에 통합되지 않은 패치의 성격을 가질 수 있다.

수정 방식들 사이에 존재하는 이러한 성격 차이는 프로그램의 이론을 가진 프로그래머에게만 의미가 있다. 동시에 프로그램 텍스트에 가해지는 변경의 성격은 프로그램이 장기적으로 생존 가능한 상태를 유지하는 데 결정적으로 중요하다.

프로그램이 품질을 유지하려면 모든 수정이 그 프로그램의 이론에 확고하게 근거해야 한다. 사실 단순성이나 좋은 구조와 같은 품질의 개념 자체도 프로그램의 이론과 관련해서만 이해할 수 있다. 그러한 품질은 동일한 실행 동작을 달성하기 위해 작성될 수도 있었지만 실제로는 프로그래머의 이해 속에서 가능성으로만 존재하는 다른 프로그램 텍스트들과 비교하여, 현재의 프로그램 텍스트가 가지는 성격을 나타내기 때문이다.

프로그램의 삶, 죽음, 그리고 부활

프로그래밍에 관한 이론 구축 관점의 핵심적인 주장 중 하나는 모든 프로그램의 필수적인 부분인 그 프로그램의 이론은 표현 가능한 것이 아니라 인간과 불가분하게 결합되어 있다는 것이다.

따라서 프로그램의 상태를 설명할 때는 그 이론을 가진 프로그래머들이 어느 정도까지 프로그램을 계속 책임지고 있는지를 나타내는 것이 중요하다. 이러한 상황을 강조하기 위한 방법으로, 프로그램 구축이라는 개념을 프로그램의 삶, 죽음, 부활이라는 개념으로 확장할 수 있다.

프로그램을 구축한다는 것은 프로그래머 팀이, 그리고 프로그래머 팀 안에서, 그 프로그램의 이론을 구축하는 것과 같다.

프로그램이 살아 있는 동안에는 그 이론을 가진 프로그래머 팀이 프로그램을 적극적으로 통제하며, 특히 모든 수정 작업에 대한 통제권을 유지한다.

프로그램의 죽음은 그 이론을 가진 프로그래머 팀이 해체될 때 발생한다. 죽은 프로그램도 컴퓨터에서 계속 실행되고 유용한 결과를 산출할 수 있다. 프로그램이 실제로 죽었다는 사실은 프로그램 수정 요구에 지능적으로 대응할 수 없게 되었을 때 비로소 드러난다.

프로그램의 부활은 새로운 프로그래머 팀이 그 프로그램의 이론을 다시 구축하는 것이다.

이러한 개념에 따르면 프로그램이 오랫동안 살아남을 수 있는지는 새로운 세대의 프로그래머가 프로그램의 이론을 이어받을 수 있는지에 달려 있다.

새로운 프로그래머가 기존 프로그램의 이론을 소유하게 되려면 프로그램 텍스트와 기타 문서를 익힐 기회를 얻는 것만으로는 충분하지 않다. 새로운 프로그래머에게 필요한 것은 이미 그 이론을 가진 프로그래머들과 긴밀하게 협력할 기회이다.

이를 통해 새로운 프로그래머는 관련된 현실 세계의 상황이라는 더 넓은 맥락에서 프로그램이 차지하는 위치를 익혀야 하며, 프로그램이 어떻게 작동하는지, 프로그램의 특이한 반응과 프로그램 수정이 그 프로그램의 이론 안에서 어떻게 처리되는지에 관한 지식을 습득해야 한다.

새로운 프로그래머에게 기존 프로그램의 이론을 가르치는 문제는, 특정한 사실이 그러하다는 지식보다 어떤 일을 어떻게 수행하는지에 관한 지식이 더 중요한 다른 활동의 교육 문제와 매우 유사하다. 글쓰기나 악기 연주가 그 예이다.

가장 중요한 교육 활동은 학생이 적절한 감독과 지도를 받으면서 해당 활동을 직접 수행하는 것이다. 프로그래밍의 경우 그러한 활동에는 프로그램과 현실 세계의 관련 측면 및 활동 사이의 관계에 관한 논의와, 프로그램이 다루는 현실 세계의 문제들에 설정된 한계에 관한 논의가 포함되어야 한다.

이론 구축 관점에서 따라오는 매우 중요한 결과는, 프로그램의 부활, 즉 문서만으로 프로그램의 이론을 다시 확립하는 것은 엄밀한 의미에서 불가능하다는 것이다.

이러한 결론이 불합리하게 보이지 않도록 덧붙이자면, 완전히 죽은 프로그램을 부활시켜야 하는 상황은 아마도 드물 것이다. 새로운 프로그래머들이 기존 프로그램의 부활을 맡게 될 때, 원래 팀이 가지고 있던 이론에 관한 지식이 전혀 없는 상태에서 작업하게 되는 경우는 상상하기 어렵기 때문이다.

그럼에도 이론 구축 관점은 프로그램의 부활을 예외적인 상황에서만 시도해야 한다는 점을 강하게 시사한다. 또한 그러한 부활은 기껏해야 많은 비용이 들며, 새롭게 부활한 이론이 원래 프로그램 작성자들이 가지고 있던 이론과 달라져 프로그램 텍스트와 불일치할 수 있다는 사실을 충분히 인식해야 한다.

이론 구축 관점에서는 프로그램을 부활시키는 대신 기존 프로그램 텍스트를 폐기하고, 새롭게 구성된 프로그래머 팀에게 주어진 문제를 처음부터 새로 해결할 기회를 주는 편이 낫다고 본다.

이러한 절차는 프로그램을 부활시키는 것보다 생존 가능한 프로그램을 만들어 낼 가능성이 높고, 비용도 더 높지 않으며 어쩌면 더 낮을 수 있다. 기존 프로그램 텍스트에 맞고 그것을 뒷받침하는 이론을 구축하는 일은 어렵고, 좌절감을 주며, 많은 시간이 드는 활동이기 때문이다.

새로운 프로그래머는 기존 프로그램 텍스트에 대한 충실성과 자신이 새로 구축해야 하는 이론 사이에서 갈등을 느끼기 쉽다. 기존 프로그램 텍스트에는 불명확한 점이나 약점이 있을 수 있고, 새로운 프로그래머가 구축하는 이론은 좋든 나쁘든 프로그램 텍스트의 바탕이 된 원래 이론과 다를 가능성이 높다.

프로그램이 계속 변화하는 프로그래머 팀에 의해 지속적으로 살아 있는 상태로 유지되는 경우에도 비슷한 문제가 발생할 수 있다. 개별 프로그래머들의 역량과 경험적 배경이 서로 다르며, 특히 팀이 계속 운영되기 위해서는 구성원들이 불가피하게 교체되어야 하기 때문이다.

방법론과 이론 구축

최근 몇 년 동안 프로그래밍 방법론에 큰 관심이 쏠려 왔다. 이 절에서는 이론 구축 관점과 프로그래밍 방법론의 바탕에 있는 개념들 사이의 관계에 관해 몇 가지 의견을 제시하겠다.

우선 프로그래밍 방법론이란 무엇인가? 특정한 방법론을 권장하는 저자들조차 이를 항상 명확하게 설명하지는 않는다.

여기서는 프로그래밍 방법론을 프로그래머를 위한 작업 규칙의 집합으로 이해하겠다. 즉 프로그래머가 어떤 종류의 일을 해야 하는지, 어떤 순서로 해야 하는지, 어떤 표기법이나 언어를 사용해야 하는지, 각 단계에서 어떤 종류의 문서를 만들어야 하는지를 알려주는 규칙의 집합이다.

이러한 방법론 개념을 프로그래밍의 이론 구축 관점과 비교할 때 가장 중요한 문제는 행위 또는 작업과 그 순서에 관한 것이다.

방법론은 프로그램 개발이 특정한 종류의 행위가 이어지는 순서로 진행될 수 있고, 또 그렇게 진행되어야 하며, 각 행위는 특정한 종류의 문서화된 결과를 낳는다는 주장을 내포한다.

그러나 이론을 구축하는 과정에는 특정한 행위의 순서가 존재할 수 없다. 사람이 보유하는 이론에는 본래적인 부분 구분도, 본래적인 순서도 없기 때문이다. 오히려 이론을 가진 사람은 질문이나 요구에 대응하여 그 이론의 바탕을 여러 가지 형태로 제시할 수 있다.

특정한 종류의 표기법이나 형식화를 사용하는 문제 역시 부차적인 문제일 수밖에 없다. 가장 중요한 대상인 이론은 표현되어 있지도 않고 표현될 수도 없기 때문에, 그 이론을 어떤 형식으로 표현할 것인지라는 문제 자체가 발생하지 않는다.

따라서 이론 구축 관점에서 보면 프로그래밍의 가장 중요한 활동을 위한 유일하게 올바른 방법론은 존재할 수 없다.

이 결론은 몇 가지 측면에서 기존의 통념과 충돌하는 것처럼 보이며, 따라서 이론 구축 관점에 반대하는 논거로 받아들여질 수 있다. 여기서는 그러한 외견상의 모순 두 가지를 다루겠다. 첫 번째는 과학을 수행할 때 방법이 중요하다는 주장과 관련되고, 두 번째는 소프트웨어 개발에 실제로 사용된 방법론들이 성공을 거두었다는 주장과 관련된다.

첫 번째 논증은 소프트웨어 개발이 과학적인 방식에 기반해야 하므로 과학적 방법과 유사한 절차를 사용해야 한다는 것이다.

이 논증의 결함은 ‘과학적 방법’이라는 것이 실제로 존재하고 과학자들에게 도움이 된다는 가정에 있다. 이 문제는 최근 여러 해 동안 많은 논쟁의 대상이 되어 왔다. 물리학의 역사를 사례로 드는 파이어아벤트와 생물학자의 관점에서 논증하는 메더워 같은 저자들은, 실제로 연구하는 과학자들에게 지침이 되는 규칙의 집합으로서 과학적 방법이라는 개념은 잘못된 것이라는 결론을 내렸다.

이러한 결론은 문제 해결에 관한 폴리아의 연구와도 모순되지 않는다. 폴리아의 연구는 수학 분야의 사례를 사용하며, 프로그래밍에도 매우 적절한 통찰을 제공한다. 그러나 그 연구가 따라야 할 하나의 방법론을 제시한다고 주장할 수는 없다. 오히려 어떠한 순서로도 적용할 수 있는 다양한 작업 방식을 제시함으로써 문제 해결자의 정신 활동을 자극하려는 제안들의 모음에 가깝다.

방법론을 배제하는 이론 구축 관점과 모순되는 것처럼 보이는 두 번째 논증은 특정한 방법론의 사용이 성공적이었다는 보고들이 출판되어 있다는 것이다.

이에 대해서는 프로그래밍 방법론의 효과를 방법론적으로 만족스럽게 조사한 연구가 지금까지 이루어진 적이 없는 듯하다고 답할 수 있다. 그러한 연구를 수행하려면 확립된 기법인 통제 실험을 사용해야 할 것이다.

그러한 연구가 부족한 이유는 부분적으로는 의미 있는 결과를 얻기 위해 필요한 연구 비용이 의심할 여지 없이 매우 높기 때문이며, 부분적으로는 프로그램 개발 분야에서 방법론이라고 부르는 것의 기초 개념들을 실제로 측정 가능한 방식으로 정의하기 어렵기 때문이다.

방법론에 관한 대부분의 출판된 보고서는 특정한 기법과 절차를 설명하고 권장할 뿐, 그 유용성이나 효과를 체계적으로 입증하지 않는다.

C. 플로이드와 여러 공동 연구자가 서로 다른 다섯 가지 방법론을 정교하게 연구한 결과, 임의의 맥락에서 기계적으로 적용하기만 하면 좋은 해결책을 만들어 내는 규칙 체계로서의 방법론이라는 개념은 환상이라는 결론에 도달했다.

그렇다면 남는 것은 프로그래머 교육에서 방법론이 미치는 효과이다. 이러한 결론은 프로그래밍의 이론 구축 관점과 완전히 양립한다.

이론 구축 관점에 따르면 프로그래머가 구축하는 이론의 품질은 전형적인 문제들에 대한 모범적인 해결책, 설명과 검증의 기법, 복잡하게 상호작용하는 여러 부분으로 이루어진 시스템을 구조화하는 원칙에 얼마나 익숙한지에 크게 의존한다. 따라서 방법론이 관심을 두는 많은 요소들은 이론 구축과 관련이 있다.

이론 구축 관점이 방법론자들의 관점과 갈라지는 지점은 어떤 기법을 어떤 순서로 사용할 것인가에 관한 문제이다. 이론 구축 관점에서는 실제로 해결해야 하는 문제를 고려하여 이를 전적으로 프로그래머가 결정해야 한다.

프로그래머의 지위와 이론 구축 관점

이론 구축 관점의 결과가 현재 널리 퍼져 있는 관점과 가장 두드러지게 대조되는 영역은 프로그래밍 활동에서 프로그래머 개인이 기여하는 바와 프로그래머에게 부여되어야 할 적절한 지위이다.

이론 구축 관점과 널리 퍼진 관점 사이에서 프로그래머 개인의 기여를 바라보는 방식의 차이는 프로그래밍에 관한 일반적인 논의 곳곳에서 드러난다.

한 가지 사례로 오스카르손이 수행한 대규모 소프트웨어 시스템의 수정 가능성 연구를 생각해 보자. 이 연구는 대규모 상용 시스템의 한 릴리스에서 이루어진 상당수의 수정 작업에 관해 광범위한 정보를 제공한다. 각 수정의 배경, 내용, 구현을 설명하며, 특히 프로그램 변경이 특정 프로그램 모듈 안에 국한되는 방식에 주목한다.

그러나 수정 사항의 구현이 프로젝트에 고용된 500명의 프로그래머들의 배경, 예를 들어 그들이 프로젝트에서 얼마나 오랫동안 일해 왔는지 등에 의존할 가능성은 전혀 언급하지 않는다. 또한 설계 결정이 500명의 프로그래머들 사이에서 어떻게 분배되는지에 관한 설명도 없다.

그럼에도 ‘결정 사항이 잘못된 블록에 구현되었다’거나 ‘AXE의 철학’이라는 표현을 사용함으로써, 기반이 되는 이론의 중요성을 간접적으로 인정하고 있다. 하지만 연구가 수행된 방식 때문에 이러한 인정은 고립된 암시에 그칠 수밖에 없다.

보다 일반적으로 프로그래밍에 관한 현재의 많은 논의는 프로그래밍이 산업 생산과 유사하다고 가정하는 듯하다. 이 관점에서 프로그래머는 생산의 한 구성 요소이며, 작업 절차에 관한 규칙으로 통제되어야 하고 쉽게 교체될 수 있는 존재로 간주된다.

이와 관련된 또 다른 관점은 인간이 규칙을 따르며 기계처럼 행동할 때 가장 좋은 성과를 낸다는 것이다. 그 결과 형식적인 표현 방식이 강조된다. 형식적인 표현을 사용하면 특정한 논증을 형식적 조작 규칙의 관점에서 공식화할 수 있기 때문이다.

이러한 관점들은 컴퓨터를 다루는 사람들 사이에 흔한 것으로 보이는, 인간의 정신은 컴퓨터처럼 작동한다는 생각과 잘 부합한다. 산업 경영의 차원에서 이러한 견해는 프로그래머를 책임이 비교적 적고 짧은 교육만으로도 충분한 노동자로 취급하는 태도를 뒷받침한다.

이론 구축 관점에서는 프로그래밍 활동의 일차적인 결과가 프로그래머들이 보유한 이론이다. 이 이론은 본질적으로 각 프로그래머의 정신적 소유물의 일부이므로, 프로그램 생산 활동에서 프로그래머를 쉽게 교체할 수 있는 구성 요소로 보는 관념은 폐기되어야 한다.

대신 프로그래머는 컴퓨터를 일부로 포함하는 활동을 책임지고 개발하고 관리하는 사람으로 여겨져야 한다. 이러한 역할을 수행하려면 프로그래머에게 안정적이고 지속적인 지위가 주어져야 한다. 또한 기업의 구성원으로서 지적인 전문성을 바탕으로 적극적으로 기여하는 엔지니어나 법률가 같은 다른 전문직과 유사한 지위를 부여받아야 한다.

이론 구축 관점이 제안하는 프로그래머의 지위 향상은 프로그래머 교육의 방향을 그에 맞게 전환함으로써 뒷받침되어야 한다.

표기법, 데이터 표현, 데이터 처리에 관한 숙련은 여전히 중요하지만, 교육의 주된 강조점은 이론을 형성하는 능력과 이해력을 발전시키는 방향으로 옮겨가야 한다.

이러한 능력을 과연 어느 정도까지 가르칠 수 있는지는 여전히 열린 문제로 남는다. 가장 희망적인 접근법은 능동적이고 건설적인 환경에서 학생들이 지도를 받으며 구체적인 문제를 직접 다루게 하는 것이다.

결론

외부 환경의 변화에 따라 요구되는 프로그램 수정이 프로그래밍의 필수적인 부분이라는 점을 받아들인다면, 프로그래밍의 주된 목적은 프로그래머가 당면한 문제들이 프로그램의 실행을 통해 어떻게 지원될 수 있는지에 관한 이론을 구축하는 것이라고 주장할 수 있다.

이러한 관점은 프로그램의 이론을 가진 프로그래머들이 프로그램을 계속 지원하는지에 따라 프로그램의 생명이 결정된다는 개념으로 이어진다.

또한 이 관점에 따르면 프로그래밍 방법론을 프로그래머가 따라야 하는 절차적 규칙의 집합으로 이해하는 것은 타당하지 않은 가정에 기반하므로 폐기되어야 한다.

이 관점에서 따라오는 또 다른 결과는 프로그래머에게 컴퓨터를 일부로 포함하는 활동을 책임지고 지속적으로 개발하고 관리하는 사람으로서의 지위를 부여해야 한다는 것이다.

프로그래머 교육에서는 데이터 처리와 표기법에 관한 지식을 습득하는 것과 더불어, 이론을 구축하는 능력을 실제로 발휘하는 일을 강조해야 한다.