Some meditations on Advanced Programming by E. W. Dijkstra
진보된 프로그래밍에 대한 몇 가지 생각 by 데이크스트라
이 글은 데이크스트라가 1962년에서 1964년 사이에 작성한 문서 Some meditations on Advanced Programming를 번역한 것입니다. 의역이 많으므로 원문과 대조해가며 읽기를 권합니다.
진보된 프로그래밍에 대한 몇 가지 생각
In case you expect me to give a complete, well-balanced and neutral survey of the advanced programming activities of the world, I must warn you that I don't feel inclined, nor entitled to do so.
My title already indicates that I am going to meditate on the subject, which is something quite different from giving a survey. Perhaps the title of my paper would have been more outspoken if it had been "My meditations on Advanced Programming" for I intend to present a picture in the way I wish to see it; and I should like to do so in all honesty without any claim to objectivity. I intend to do so because I have a feeling that I serve you better by giving you an honest personal conviction than by presenting you with the colourless average of conflicting current opinions of other people.
만약 여러분이 완전하고 균형잡혔으면서도 중립적인 관점을 기대하면서 이 글을 읽기 시작했다면, 나는 그럴 생각도 없고 그럴 자격도 없음을 일러두고자 합니다.
이 글의 제목을 보면 알 수 있듯이 나는 이 주제에 대해 곰곰히 생각해 보고자 하며, 이는 검토(survey)와는 상당히 다른 작업입니다. 제목이 "진보된 프로그래밍에 대한 나의 생각"인 이유는 내가 바라보고 싶은 그림을 제시하고 객관성 같은 것은 크게 신경쓰지 않는 더 솔직한 내용을 담기 위해서입니다. 나는 색깔 없는 흔해 빠진 대중적인 의견을 늘어놓는 것보다 개인적으로 확신하는 것을 정직하게 보여주는 것이 더 낫다고 생각합니다. 그래서 이 글에서는 그렇게 하려고 합니다.
You will observe that I fail to give you a generally acceptable definition of the subject "Advanced Programming". I think that in my own appreciation of the subject the description "Advancing Programming" would have been a better qualification. I do like many activities which are worthy, I think, of the name "Advanced Programming" but I don't like these activities so much for the sake of their output, the programs that have resulted from them, as for what these activities can teach us. And if I am willing to study them, to meditate upon them, I am willing to do so in the hope this study or these meditations will give me a clearer understanding of the programmer's task, of his ends and his means. Therefore I should like to draw your attention in particular to those efforts and considerations which try to improve "the state of the Art" of programming, maybe to such an extent that at some time in the future we may speak of "the state of the Science of Programming".
And a little look around us will convince us that this improvement is very urgent, for on the whole the programmer's world is a very dark one with only just the first patches of a brighter sky appearing at the horizon. For the present-day darkness in the programmer's world the programmers themselves are responsible and nobody else. But before we put too much blame on them, look for a moment how their world came into existence.
이 글에서 나는 "진보된 프로그래밍"이라는 주제에 대해 일반적으로 납득 가능한 정의를 제시하지는 않습니다. 그러나 나는 내가 "진보된 프로그래밍"이라는 주제에 대한 의견은 낼 수 있는 사람이라 생각합니다. 왜냐하면 나는 "진보된 프로그래밍"이라는 주제에 걸맞는 다양한 가치있는 활동을 매우 좋아하면서도 그와 동시에 그런 작업의 결과물로 나온 프로그램이나 그를 통해 배울 수 있는 것이 무엇인지에 대해 비판적인 생각도 갖고 있기 때문입니다. 내가 이 주제에 대해 연구하고 생각해보려는 이유는 프로그래머들이 하는 업무와 그 목적, 그리고 프로그래머 자체에 대한 더 명확한 이해를 끌어내보고 싶어서입니다. 나는 미래의 언젠가는 "프로그래밍의 과학적 특성"으로 대체될 현재의 프로그래밍의 "예술적 관행"을 개선하기 위한 노력과 대책에 대해 주목하고자 합니다.
주위를 둘러보면 이 문제에 대한 개선이 매우 시급하다는 것을 알 수 있습니다. 프로그래머들의 세계는 전반적으로 어둠에 휩싸여 있고 이제 지평선에서 간신히 동이 트고 있는 상황입니다. 그리고 이 암담함은 프로그래머들이 스스로 초래한 것이지만, 프로그래머들을 탓하기 전에 먼저 어쩌다 세상이 이렇게 되었는지에 대해 먼저 알아보도록 합시다.
When the first automatic electronic computers started to work more or less properly, mankind was faced with a new technical wonder, with a most impressive achievement of technical skill. And, as a result, everybody was highly impressed and rightly so. Under these circumstances it was completely natural that the structure of these early machines was mainly decided by the technical possibilities at that time. And under these circumstances it would have been an undreamt of undecency if programmers had dared to suggest that those clever designers had not built at all the machines that programmers should like to have. Therefore this thought hardly struck the programmers' minds. On the contrary: faced on the one hand with the new computers and on the other hand heaps of problems waiting for their solution, they have done their utmost best to accomplish the task with the equipment that had become available. They have accepted the full challenge. The potentialities of the computers have exhausted to slightly beyond their utmost limits, the nearly impossible jobs have yet been done by using the machines in all kinds of curious and tricky ways, which were completely unintended and even not foreseen by the designers. In this atmosphere of pioneering, programming has arisen not as a science but as a craft, as an occupation where man, under the pressure of the circumstances was guided more by opportunism than by sound principles. This —I should like to call it "unhygienic"— creativity and shrewdness of the programmers has had a very bad influence on machine designers, for after some time they felt free to include all kinds of curious facilities of doubtful usability, reassuring themselves by their experience that, no matter how crazy a facility they provided, always a more crazy programmer would emerge that would manage to turn it into something profitable —as if this were sufficient justification for its inclusion.
최초의 전자식 자동 컴퓨터가 돌아가기 시작한 것은 인류가 처음으로 직면한 기술적으로 경이로운 사건이면서 동시에 가장 인상적인 기술적 성취였습니다. 모든 사람이 깜짝 놀랐죠. 그런 시대에 당시의 기술적 가능성을 토대로 초기 컴퓨터의 구조가 결정된 것은 너무 당연한 일이었습니다.
그런 것을 해낸 똑똑한 설계자들에게, 프로그래머들이 자기네들이 생각하는 이상적인 기계를 만들지 않았다면서 불평하는 일은 상상도 할 수 없는 일이었습니다. 그리고 그렇게 생각하는 프로그래머가 있지도 않았습니다.
당시의 프로그래머들은 한 쪽으로는 새로운 컴퓨터를 마주하게 되었고, 다른 한 쪽으로는 해결책을 기다리는 많은 문제들 사이에 끼어 있었다고 할 수 있습니다. 그들은 이런 도전적인 상황을 받아들여 사용 가능한 장비로 어떻게든 일을 해내기 위해 최선을 다했습니다. 그런데 이들은 설계자가 의도하지도 않았고 상상하지도 못했던 괴상하고 신기한 방법으로 컴퓨터의 잠재력을 한계까지 끌어내서 불가능하다고 여겨졌던 작업들을 해치우게 되었습니다.
이런 선구적인 분위기에서 프로그래밍은 상황적 한계 속에서 바람직한 원칙이 아니라 편의주의를 토대로 진행되어 과학이 아니라 하나의 공예로 인식되고 말았습니다.
나는 이러한 세태를 "비위생적"이라 부릅니다. 프로그래머의 창의성과 영민함은 기계 설계자에게 매우 나쁜 영향을 끼쳤습니다. 시간이 좀 흐르고 나서 설계자들이 사용성이 의심스러운 기능을 추가하는 것을 아무렇지 않게 여기게 됐기 때문입니다. 아무리 정신나간 것 같은 기능을 추가해도 더 미친놈 같은 프로그래머가 나타나서 그걸 활용해 성과를 내는 것을 경험해버렸기 때문에 안심하고 합리화하여 더는 이상하게 생각하지 않게 된 것입니다.
In the mean time programming established itself as a discipline where on the whole standards for quality were extremely crude and primitive. The main —and often only— possible virtues of a program were its quantitative characteristics, viz. its speed and its storage requirements. Space and time became the exclusive aspects of efficiency. And in various places these standards are still in full vigour: not so long ago I heard of two cases, one where a machine was not bought because its multiplication speed was too low —and this may be a valid argument— and another case where a certain machine was selected because its multiplication was so fast. And this last decision was taken without the validity of this criterion being questioned.
따라서 프로그래밍은 도제적이며 극도로 조잡하고 원시적으로 품질을 관리하는 분야로 자리잡게 되었습니다.
프로그램의 핵심적이면서도 가능한(어떤 경우에는 유일한) 장점은 바로 특유의 실행 속도와 저장 공간에서 비롯되는 양적 특성입니다. 공간과 시간은 효율성의 관점에서 배타적인 요소이며 대부분의 업계에서 이 기준은 표준이나 다름없습니다. 나는 얼마 전에 두 가지 사례에 대한 이야기를 들었습니다. 첫 번째 기계는 곱셈 연산 속도가 너무 느려서 판매로 이어지지 않았습니다. 합리적인 결정이죠. 그리고 두 번째 기계는 곱셈 연산 속도가 너무 빠르기 때문에 선택되었습니다. 후자의 결정이 타당하다는 점에 대해서는 누구도 의문스러워하지 않았습니다.
Apart from the programs that have been produced, the programmers' contribution to human knowledge has been fairly useless. They have concocted thousands and thousands of ingenious tricks but they have given this chaotic contribution without a mechanism to appreciate, to evaluate these tricks, to sort them out. And as many of these tricks could only be played by virtue of some special property of some special machine their value was rather volatile. But the tricks were defended in the name of the semi-god "Efficiency" and for a long time there was hardly an inkling that there could be anything wrong with tricks. The programmer was judged by his ability to invent and his willingness to apply tricks. And also this opinion is still a wide-spread phenomenon: in advertisements asking for programmers and in psychological tests for this job it is often required that the man should be "puzzle-minded", this in strong contrast to the opinion of the slowly growing group of people who think it more valuable that the man should have a clear and systematic mind.
방금 만들어진 프로그램들을 제외하고 생각하면, 프로그래머들이 인류의 지식에 기여한 것은 상당히 쓸모없는 것들입니다. 그들이 꼬아서 만들어낸 수많은 기발한 트릭은 정당하게 평가하고 분류할 수 없으므로 몹시 난잡하고 혼란스럽습니다. 이런 트릭들 대부분은 일부 특수한 기계의 특수한 속성을 통해서만 돌아가기 때문에 확실한 가치를 갖고 있는 것도 아닙니다. 하지만 "효율"이라는 마법의 단어가 이런 트릭들을 보호해 주었으므로 이런 상황을 문제삼는 경우도 거의 나타나지 않았습니다.
발명능력 뿐 아니라 트릭을 적용하려는 욕심을 얼마나 갖는지가 프로그래머를 평가하는 기준이 되어버린 것입니다.
이런 경향은 여전히 널리 퍼져있는 현상입니다. 프로그래머를 찾는 구인 광고나 프로그래머 자격을 따지곤 하는 심리 테스트 같은 것에서는 "puzzle-minded"를 필수적으로 강조하곤 합니다. 이는 명쾌하고 체계적인 사고방식을 것을 더 바람직하게 생각하는 점진적인 성장 그룹의 선호와는 매우 대조되는 것입니다.
But, as I told you, the sky above the programmer's world is brightening slowly. Before I am going to draw your attention to some discoveries that are responsible for this improvement I should like to state as my opinion that it is relatively unimportant whether these discoveries are really new discoveries or whether they are rediscoveries of things perfectly well known to people like, say, Turing or von Neumann. For in the latter case the important and new thing is that a greater number of people become aware of such a fact and that a greater number of people realize that these considerations are not just theoretical considerations but that they may have tangible, practical results. In this light one might feel inclined to summarize the achievements of advanced programming as some purely educational successes: "At last programmers have started to educate one another to at least some extent.". I shall not protest against this summary provided one agrees with my opinion that mutual education is one of the major difficult tasks of mankind.
하지만 위에서 말한 것처럼 프로그래머 세계는 서서히 동이 트고 있습니다.
이런 개선에 핵심적인 몇 가지 발견을 소개하기 전에, 이 발견들이 정말 새로운 것인지 아니면 앨런 튜링이나 폰 노이만과 같은 사람들의 무언가를 재발견한 것인지는 상대적으로 덜 중요하다는 것을 말해두고 싶습니다. 왜냐하면 후자의 경우라면 더 많은 사람들이 그것이 단지 이론일 뿐 아니라 다양한 상황에서 실제 결과를 끌어낼 수 있음을 깨닫는 것이 매우 중요하기 때문입니다.
이러한 관점에서 보면, 어떤 사람은 진보한 프로그래밍의 성취를 순수한 교육적 측면에서의 성공으로 해석하기도 할 것입니다. "드디어 프로그래머들이 서로에게 최소한도의 교육을 시켜주기 시작했습니다"라고 말이죠. 만약 그런 해석을 하는 사람이 서로를 교육하는 것이 우리 인류에게 있어 중요한 과제 중 하나라는 내 의견에 동의한다면 나는 그 해석에 이의를 제기하지 않을 것입니다.
Some fifteen or ten years ago the design and construction of a new, unique computer was a well-established and respectable occupation for University Laboratories. And each of these "laboratory machines" were, in their own private ways, revolutionary contraptions. From then onwards this custom died out and design and construction of automatic computers became more and more an exclusively industrial activity. Five years ago most of us felt this as a perfectly natural development: construction of new computers became an extremely costly affair and it was generally felt that the time had come to leave this activity to the specialized industries. Now, five years later, we can only regret this development, for the computers on the market today are, on the whole, very disappointing. All right, they are faster, they are much more reliable than the old laboratory machine, but, on the other hand, they are often boring, uninspiring and hopelessly old-fashioned as well. For instance, the commercial requirement that all the programs made for some older machine from the same manufacturer should, without any modification, be acceptable to the new machine has led to the design of new machines the order code of which included the order code of the previous one in its entirety. Such a policy, however is a never failing mechanism to prolong the lifetime of previous mistakes. Some time ago we were offered the slogans about "the computers of the second generation", but to my taste many of them were as dull as their parents. Apparently a nice computer has at least one property in common with a gentleman, viz. that it takes at least three generations to produce one! Most of the industries, particularly the bigger ones, proved to be very conservative and reactionary. They seem to design for the customer that believes the salesman who tells him that machine so-and-so is just the machine he wants. But the poor customer who happened to know already, all by himself, what he wants is often forced to accept a machine with which he is already disgusted before the thing is installed in his establishment. Under the present circumstances, it is, commercially speaking, apparently not too attractive to put a nice computer on the market. This is a sorry state of affairs, many a programmer suffers regularly from the monstrosity of his tool and we can only hope for a better future with nicer machines. In the mean time he can program; taking some efficiency considerations for granted he can force his machine to behave as he wishes: when making a programming system he designs a machine as it should have been. Thanks to the logical equivalence between designing a machine and making a program, programmers can contribute to future machine design, by exploring on paper, in software, the possibilities of machines with a more revolutionary structure.
새롭고 독특한 컴퓨터를 설계하고 제작하는 것은 10에서 15년 전만 해도 대학 연구실 업계에서 인정받고 존경받는 대단한 일이었습니다. 이런 "연구실 기계" 각각은 자신만의 독특한 구조를 갖는 혁명적인 장치들이기도 했습니다.
그러나 그 이후로 시간이 흐르며 자동 컴퓨터의 설계와 제작은 점점 독점적인 산업으로 변화해갔습니다. 5년 전의 우리들은 이런 변화를 자연스러운 것으로 받아들였습니다. 새로운 컴퓨터를 제작하는 것이 엄청나게 비싼 일이 되었으니까 이런 쪽에 특화된 기업에 맡기는 것이 바람직한 시기가 되었다고 느낀 것입니다.
그런데 우리는 5년 전의 변화를 후회하고 있습니다. 최근 시판되고 있는 컴퓨터들이 전반적으로 무척 실망스럽기 때문입니다. 물론 최신 컴퓨터들은 오래된 연구실 기계들보다 더 나은 신뢰성을 갖추고 있으며 더 빠르기도 합니다. 하지만 좀 답답한 면이 있고 딱히 영감을 주지도 않으며 절망적일 정도로 구식입니다.
예를 들어 봅시다. 같은 제조사에서 생산한 몇몇 구형 기계를 작동시키기 위해 만든 프로그램들이 있는 상태에서, 신형 기계에서도 오래된 프로그램들이 수정 없이도 모두 돌아가야 한다는 업체 요구사항이 있었습니다. 이 요구사항 때문에 새로 만들어진 컴퓨터는 이전 컴퓨터의 명령 코드를 전부 포함하게 되었습니다. 이런 해결책은 과거에 저지른 실수의 수명을 늘려주는 확실한 방법이죠.
얼마전에는 "2세대 컴퓨터"에 대한 제안을 받았는데, 내 취향에 그 컴퓨터는 별로 세련되지도 않았고 이전 세대 컴퓨터와 별로 다를 바가 없었습니다. 뛰어난 컴퓨터와 훌륭한 신사는 한 가지 공통점을 갖습니다. 바로 삼대는 흘러야 제대로 된 하나를 배출한다는 것이죠!
대부분의 기업체, 특히 큰 규모의 기업들이 매우 보수적이고 느리게 움직인다는 것은 상식입니다. 이런 기업들은 별로 안 좋은 기계를 영업하면서 이게 바로 당신에게 딱 맞는 컴퓨터라고 하는 판매사원의 말을 곧이곧대로 믿는 고객에게 팔기 위한 컴퓨터만 설계하는 것처럼 보입니다. 하지만 불쌍한 고객은 자신이 원하는 것을 이미 알고 있습니다. 즉 별로 마음에 안 드는 짜증나는 기계를 자신의 연구소에 설치하도록 강요당하고 있는 것입니다.
요즘 세태에서 훌륭한 컴퓨터를 시장에 내놓는 것은 상업적으로 썩 매력적인 일이 아닐 수 있습니다. 이는 안타까운 일입니다. 많은 프로그래머들이 끔찍한 도구를 사용하면서 정기적으로 고통받고 있기 때문입니다. 우리는 그냥 앞으로 더 좋은 기계를 사용하는 것만을 바랄 뿐입니다. 그리고 그렇게 되었을 때에서야 비로소 '자신이 바라는대로 컴퓨터가 작동하게 하면서 효율성도 함께 고려하는' 진정한 프로그래밍이 가능해질 것입니다. 그렇게 되면 컴퓨터의 구조 또한 프로그래밍 시스템을 위한 가장 바람직한 형태로 설계될 것입니다.
기계를 설계하는 것과 프로그램을 만드는 것이 논리적으로 동등하다는 것은 감사한 일입니다. 그로 인해 프로그래머는 논문을 탐독하고 소프트웨어를 작성하는 것으로 보다 혁명적인 구조를 가진 기계의 가능성을 탐구하고, 미래의 기계 설계에 기여하게 될 수 있기 때문입니다.
The equivalence of making a program and designing a machine has another, may be far-reaching consequence of a much more practical nature. It is not unusual to regard a classical computer as a sequential computer coupled to a number of communication mechanisms for input and output. Such a communication mechanism, however, performs in itself a sequential process - usually of a cyclic nature, but that feature is of no importance now. For this reason we can regard a classical machine, communication mechanism included, as a group of loosely connected sequential machines, with interlocks, where necessary, to prevent them to get too much out of phase with one another. The next step is to use the central computer not for only one sequential process but to equip it with the possibility to divide its attention between an arbitrary number of such loosely connected sequential processes. One can do so with complete preservation of the symmetry between the sequential processes to which a distinct piece of hardware corresponds on the one hand and those taken care of by the central computer on the other hand. Or even by one of the central processors, as the case may be. The difference between a modest and an ambitious installation may be that a couple of sequential processes, that in the modest installation are performed by the central computer, are performed by private hardware in the ambitious installation. But the above mentioned equivalence between designing a machine and making a program, between performing a process either by hardware or by software, should be exploited to guarantee that the program acceptable for the one installation is also acceptable for the other. The above considerations are important because a machine rigorously designed along the above lines would greatly facilitate the manufacturer's task to equip his product with the required software. The moral of this is that, if at the present moment many manufacturers have great difficulties in fulfilling their software obligations and if one of the main sources of their trouble is that no two installations of the same machine are identical, their trouble could very well be a self-inflicted pain.
프로그램 제작과 기계 설계 사이의 동등성은 서로 다른 방향에서의 실용적인 접근으로 인해 비롯된 일이기도 합니다.
고전적인 컴퓨터란 무엇인가에 대해 생각할 때, 입력을 받아서 출력을 내놓기 위한 여러 개의 통신 메커니즘들을 실행하기 위해 순차적으로sequential 연결된 여러 컴퓨터로 여기는 것은 드문 일이 아닙니다. 그런데 통신 메커니즘이 바로 순차적 프로세스를 수행하는 것입니다(보통은 순환하는cyclic 방식으로 작동하지만 상세 기능을 따지는 것은 여기에서는 중요하지 않습니다).
그렇다면 다음 과제는 중앙 컴퓨터를 순차적 프로세스에만 사용하는 것이 아니라, 느슨하게 연결된 순차적 프로세스 중 임의의 수의 프로세스로 중앙 컴퓨터의 주의를 분산시킬 수 있도록 하는 것입니다. 그렇게 되면 우리는 고전적인 컴퓨터를, 통신 메커니즘을 포함하고 있는 느슨하게 연결된 순차적sequential 기계들의 그룹으로 생각할 수 있게 됩니다. 서로간의 연결 단계가 잘 맞지 않는 것을 방지하는 것이 필요하다면 인터락interlocks을 사용하도록 합니다. 별도의 하드웨어 조각이 처리하는 순차 프로세스와, 중앙 컴퓨터가 처리하는 프로세스. 양쪽 사이의 조화를 완전히 보장한다면 이렇게 하는 것이 가능합니다. 물론 상황에 따라 중앙 프로세서 중 하나가 혼자서 처리하는 경우도 있을 수 있습니다.
이런 과감한 구조는 평범한 하드웨어 구조와 차이점이 있습니다. 평범한 하드웨어 구조에서는 중앙 컴퓨터 혼자서 순차적 프로세스를 실행하지만, 이 구조에서는 순차적 프로세스의 몇 가지를 개인 하드웨어에서 가동하게 됩니다.
그리고 앞서 언급했던 '기계 설계와 프로그램을 만드는 것 사이의 동등성'을 떠올려 보면, 양쪽 중 어느 구조를 갖는 하드웨어나 소프트웨어로 실행하건 간에 프로그램을 동등하게 실행할 수 있도록 보장해줘야 합니다. 이것은 중요한 개념입니다. 이 개념에 따라 엄격하게 설계된 기계는 제조업체가 제품에 필수적인 소프트웨어를 장착하는 작업이 대단히 편해지기 때문입니다. 현재 많은 제조업체들이 소프트웨어 제공의무를 이행하는 데에 매우 큰 어려움을 겪고 있으므로 이는 좋은 지침이 될 것입니다. 그들이 겪는 문제의 원인은 주로 동일한 기계라 하더라도 두 가지 방식으로 설치하게 되면 똑같이 작동하지 않게 된다는 것 때문입니다. 제조업체들의 문제는 자업자득이라 할 수 있겠습니다.
In this connection I should like to mention that I am fully aware of the fact that my previous picture of the commercial computer market was somewhat one-sided. Many of you will realize that at least one of the commercial products shows a great number of the "nice properties" just mentioned. In my opinion, this particular computer should be regarded as one of the brightest patches in the sky.
이와 관련하여 상업용 컴퓨터 시장에 대한 나의 이전 그림이 좀 일방적이었다는 것을 말해두고 싶습니다. 상업적인 제품들 중 적어도 한 제품은 위에서 언급한 "좋은 특성들"을 갖고 있다는 것을 여러분들 중 대부분이 깨닫게 될 것이기 때문입니다. 내 생각에 그 특별한 컴퓨터는 프로그래머 세상에서 가장 밝은 부분 중 하나로 평가받아야 합니다.
Now I am turning my attention to one of the most important facts that happened in the programmers world since the UNESCO Conference in 1959, viz. the publication of the famous "Report on the Algorithmic Language ALGOL 60", edited by Dr Peter Naur. I shall not discuss here the merits of the language ALGOL 60, nor shall I go into the question whether it has reached its original aims or not. I intend to restrict myself to a discussion of the consequences of this publication, of the influence it has had in the world of programming. For, this influence has been tremendous. In a short summary I could formulate as follows: through its merits ALGOL 60 has inspired a great number of people to make translators for it, through its defects it has induced a great number of people to think about the aims of a "Programming Language". ALGOL 60, in all probability and in accordance with the wish of its authors, will be superseded by some better language in due time, but much, much longer we shall be able to trace its educational effects.
이제 나는 1959년의 유네스코 컨퍼런스 이후 프로그래머 세계에서 일어난 가장 중요한 사건인, Peter Naur 박사가 쓴 유명한 논문 "알고리즘 언어 ALGOL 60에 대한 보고서"Report on the Algorithmic Language ALGOL 60를 주목하고자 합니다.
나는 ALGOL 60 언어의 장점에 대해 이야기할 생각도 없고, ALGOL 60이 목적을 달성했는지에 대해서도 이 글에서 다루지 않을 것입니다. 나는 그 논문이 프로그래밍 세계에 미친 영향에 대해 집중하고자 합니다. 왜냐하면 그 영향력이 엄청났기 때문입니다.
나는 이렇게 요약할 수 있다고 생각합니다.
- ALGOL 60의 장점은 수많은 사람들에게 영감을 주었으며 그들이 ALGOL 60의 번역기를 만들도록 했습니다.
- 그리고 ALGOL 60의 단점은 수많은 사람들에게 "프로그래밍 언어"라는 것의 목적에 대해 생각하도록 유도했습니다.
ALGOL 60은 만든 사람들의 희망에 따라 더 나은 언어로 대체될 것입니다. 그러나 우리는 훨씬 더 오랜 기간동안 이 언어의 교육적 효과를 누리게 될 것입니다.
Programming language, translator and computer, these three together for a tool, and in thinking about this tool as a whole, new dimensions have been added to the old concept of "reliability". In connection with the third of the three components, viz. the computer, concern about its reliability is as old as computers themselves, the acceptance test is a well-known phenomenon.
프로그래밍 언어, 번역기, 컴퓨터. 이 세가지를 하나의 도구로 사용하게 되면서 "신뢰성"reliability이라는 오래된 개념에 새로운 차원이 추가되었습니다. 세 가지 요소 중 세번째에 해당하는 컴퓨터의 신뢰성에 대한 우려는 컴퓨터가 탄생했을 때부터 있어왔던 것입니다. 인수 테스트acceptance test는 상식이기도 합니다.
But what is the value of an acceptance test? It is certainly no guarantee that the machine is correct, that the machine acts according to its specifications. It only says that in these specific test programs the machine worked correctly. If the design is based on some critical assumption, we can only conclude, that in these test programs the corresponding critical situations apparently did not arise. If the design still contains logical errors, we can conclude, that in these specific test programs these logical errors apparently did not matter. But as a user, we are not interested in the test programs, we are interested in our own programs. And from the successful acceptance test we should like to conclude that the machine works correctly in our programs also! But we cannot draw this conclusion. The best thing that a successful acceptance test can do is to strengthen our believe in the machine's correctness, to increase the plausibility that it will perform any program in accordance with the specifications. The basic property of the program of the user is that it will certainly require from the machine to perform actions it has never done before. Machine designers have seen this difficulty quite clearly. They have realized that the successful acceptance test has only value as far as future programs are concerned, provided the actions performed in the test programs can be regarded as representative for all its possible operations. And they can only be representative by virtue of the clean and systematic structure of the machine itself. The above is common knowledge among machine designers; curiously enough, this is not true for translator makers, for whose activity the same considerations apply.
그런데 인수 테스트는 가치있는 것일까요? 기계가 스펙에 따라 정확하게 작동한다는 보장은 어디에도 없습니다. 그냥 특정한 테스트 프로그램에 한해서 기계가 올바르게 작동했다는 것만 알 수 있을 뿐입니다. 몇 가지 중요한 전제를 토대로 하고 있는 설계를 테스트할 때에도, 우리는 그냥 테스트 프로그램을 진행하는 동안에 치명적인 문제가 나타나지 않았다는 결론을 내리는 정도입니다. 만약 설계 자체에 논리적 오류가 포함되어 있다면 테스트 프로그램에서 논리적 오류가 나타나는 것은 당연한 일입니다.
사용자로서의 우리는, 테스트 프로그램에는 별로 관심이 없습니다. 우리의 관심은 우리 프로그램에 있습니다. 인수 테스트가 성공하는 것만으로도 우리 프로그램도 같은 기계에서 올바르게 작동한다는 확신을 얻고 싶다는 거죠! 하지만 이런 결론을 내리는 일은 가능하지 않습니다.
기계의 정확성에 대해 우리에게 확신을 주고, 스펙을 따르는 모든 프로그램의 실행 가능성을 높여줄 수 있을 때 성공한 인수 테스트는 좋은 인수 테스트가 됩니다. 사용자 프로그램의 기본 속성은 기계가 이전에 해본 적이 없는 새로운 작업을 시켜본다는 겁니다. 기계 설계자들은 이런 어려움을 분명하게 알고 있습니다. 그들은 테스트 프로그램에서 검사한 것들이 발생 가능한 모든 작업을 대표하는 것으로 간주할 수 있다면, 성공적인 인수 테스트가 향후의 프로그램과 관련된 가치를 갖는다는 것을 깨달았습니다. 그리고 기계가 자체적으로 깨끗하고 체계적인 구조를 가질 때에만 그것이 가능하게 됩니다. 이 내용은 놀랍게도 기계 설계자들 사이의 일반 상식이기도 합니다. (신기하게도 번역기 제조사는 해당되지 않는데, 같은 고려사항이 적용되는데도 그렇습니다.)
In order that the tool, consisting of programming language, translator and machine, be a reliable tool, it is, of course, mandatory that all its components be reliable. One should expect that the translator maker, who in contrast to the machine designer has to deal with logical errors only, should do his job at least as well as the machine builder. But I am afraid that the converse is true. At the Rome Conference last spring I was surprised to hear that the extensive translators for symbolic languages constructed in the United States continued to show up errors for years. I was shocked, however, when I saw the fatalistic mood in which this sorry state was accepted as the most natural thing in the world. This same attitude is reflected in the terms of reference of an ISO committee which deals with the standardization of programming languages: there one finds the recommendation to construct for any standard language a set of standard test examples on which any new translator for such a language could be tried out. But no hint that the correct processing of these standard test examples obviously is only a trivial minimum requirement, no trace of the consideration that our belief in the correctness of a translator can never be found on successful tests alone, but is ultimately derived from the clean and systematic structure of the translator and from nothing else. In deciding between reliability of the translation process on the one hand and the production of an efficient object program on the other hand the choice often has been decided in favour of the latter. But I have the impression that the pendulum is now swinging backwards.
프로그래밍 언어, 번역기, 기계로 이루어진 도구가 신뢰성을 갖추려면 당연히 각 구성 요소가 먼저 신뢰성을 갖추고 있어야 합니다. 그리고 논리적 오류만을 처리하는 번역기 제조사의 경우에는 기계 설계자들이 해놓은 것만큼의 일만 해도 된다고 생각할 수 있습니다. 그러나 나는 실상이 그와 반대인 것을 걱정합니다.
지난 봄, 로마에서 있었던 컨퍼런스에 갔다가 미국에서 만들어진 대표적인 언어들을 광범위하게 지원하는 번역기들이 지난 몇 년째 에러를 내고 있다는 이야기를 듣고 깜짝 놀랐습니다. 에러가 계속 나고 있는 안타까운 상황이 어쩔 수 없는 자연스러운 일로 받아들여져 있는 분위기를 보고 충격을 받은 것입니다. 나의 이런 반응은 프로그래밍 언어의 표준을 다루는 ISO 위원회의 방침과 통하는 바가 있습니다. 표준 언어를 위한 번역기를 만들 때 필요한 표준 테스트 예제 셋이 그 표준에 있기 때문입니다.
하지만 생각해 보면 표준 테스트 예제를 정확히 처리하는 것은 사소한 최소 요건일 뿐이며, 번역기의 정확성에 대한 우리의 신뢰가 성공적인 테스트를 통해서만 얻는 것도 아닙니다. 결국 신뢰는 번역기의 깨끗하고 체계적인 구조를 통해 얻어내는 것입니다.
한편 번역 프로세스의 신뢰성과 목적 프로그램을 효율적으로 생산하는 것 사이에서 저울질 하는 경우를 생각해 볼 때 대부분은 후자가 선택되곤 했습니다. 그러나 나는 그런 추세가 역전되고 있는 것을 느끼고 있습니다.
For instance: if one gets a much more powerful machine in one's establishment than the one one had before, one can react to this in two different ways. The classical reaction is that the new machine is so much more expensive, that it is ever so much more mandatory that no expensive computing time of the new machine should be wasted, that the new machine should be used as effectively as possible, etc. etc.. On the other hand one can also reason as follows: as the new machine is much faster, time does not matter so very much any more; as in the new computer the cost per operation is less than in the previous one, it becomes more realistic to investigate whether we can invest some of the machine's speed in other things than in sheer production, say in convenience for the user —what we do already when we use a convenient programming language— or in elegance and reliability of the translator, thus increasing the quality of our output.
예를 들어 봅시다. 만약 어떤 사람이 이전에 갖고 있던 것보다 훨씬 더 강력한 기계를 갖게 된다면 다음의 두 가지 방식으로 사용하게 될 것입니다.
전통적인 방법은 새 기계가 훨씬 더 비싸니까 새 기계의 값비싼 계산 시간을 낭비하지 않는 것이 중요하다고 생각합니다. 따라서 새 기계를 가능한 한 효율적으로 덜 사용하는 방향으로 접근합니다.
그러나 이렇게 하는 방법도 있습니다. 새 기계가 훨씬 빠르니까 시간을 따지는 것은 중요하지 않다고 생각하는 겁니다. 새 컴퓨터에서 작업을 처리하는 비용이 이전 컴퓨터보다 더 싸니까, 사용자의 편의를 위한 (편리한 프로그래밍 언어에서 이미 써먹고 있는) 다른 작업에 기계의 속도를 투자해도 되는지를 따져보는 현실적인 문제를 검토하게 됩니다. 또는 우아하고 신뢰성있는 번역기를 사용해 출력 품질을 향상시킬 수도 있습니다.
Also it is more widely recognised now than a couple of years ago that the construction of an optimizing translator is, essentially, a nasty job. Optimizing means improving the object program, i.e. making a more efficient object program than the one produced by straightforward, but reliable and trustworthy translation techniques. Optimization means "taking advantage of a special situation". Well, if one optimizes in one respect, it is not an impossible burden to verify that the shortcut introduced in the object program does not lead to undesired results. If, however, one optimizes in two different respects, the duty of verification becomes much harder, for one has to verify not only that the two methods are correct in themselves, but one must also check that they do not interfere with one another. If one optimizes in more different respects, the task to create confidence in the translator's correctness explodes exponentially. As a result it is no longer possible to recommend a computer by pointing to, say, the size of the translators available for it. On the contrary: the more extensive and shrewd a translator is, the more doubtful is its quality. And further: for the necessity of such extensive optimization efforts one might, finally, blame the computer in question: if we really need such an intricate process as an optimizing translation to load our programs one feels inclined to defend the opinion that, apparently, the computer is not too well suited for its task. In short, the construction of intricate optimizing translators is an act the wisdom of which is subject to doubt and there is certainly a virtue in efforts to remove the need for them, e.g. the design of computers where these optimization tricks don't pay, or at least don't pay so much.
한편 번역기를 최적화하는 작업이 본질적으로 까다로운 일이라는 사실은 몇 년 전에 비해 더 널리 알려졌습니다. 여기에서 말하는 최적화란 목적 프로그램을 향상시키는 것, 즉 단순하지만 신뢰할 수 있는 번역기 테크닉을 사용해 만들고 있는 것보다 더 효율적인 목적 프로그램을 만드는 것을 말합니다.
최적화Optimization란 "특별한 상황의 이점을 취하는 것"을 의미합니다. 한 가지 측면에서 최적화를 했다고 합시다. 그럴 때 그 최적화가 목적 프로그램의 결과를 이상하게 바꾸지 않는지를 검사하는 것은 그닥 어려운 일이 아닙니다. 하지만 두 가지 측면에서 최적화를 해버리면 검증하기가 상당히 어려워집니다. 일단 두 방법이 올바른지 확인해야 하며, 두 방법이 서로에게 영향을 주고 있지는 않은지도 검사해야 하기 때문입니다. 즉 더 많은 측면에서 최적화를 수행하게 되면 번역기의 정확성에 대해 신뢰를 만들어내기가 기하급수적인 난이도로 폭발하는 것입니다. 따라서 번역기가 사용 가능한 용량을 기준으로 컴퓨터를 추천할 수 없게 됩니다.
한편으로는 더 넓은 범위를 포괄하는 더 똑똑한 번역기일수록 그 품질이 더 의심스럽게 됩니다. 그리고 한 단계 더 나아가서, 그런 최적화가 정말 필요한 게 맞는지를 따지다가 컴퓨터가 쓸모 있는 게 맞는지를 논하게 될 수도 있습니다. 만약 프로그램을 로드하려고 그런 복잡한 프로세스를 거쳐 번역기를 최적화하는 것까지 해야 한다면, 과연 컴퓨터가 그 작업에 적합한가 하는 의견이 나오게 되는 것입니다.
간단히 말해 복잡하게 최적화된 번역기를 구축하는 일은 의문스러우면서도 지혜로운 행동이라 할 수 있습니다. 그리고 최적화 트릭이 오히려 비용을 낭비하거나 더 이상의 비용을 들이기 곤란한 컴퓨터 구조라면 번역기가 쓸모없다고 여겨 없애려는 것 또한 나름의 장점이 있습니다.
With regard to the structure of a translator, ALGOL 60 has acted a great promoter of non-optimizing translators. The fact is that the language as it stands is certainly not an open invitation for optimization efforts. For those that thought they knew how to write optimizing translators —be it for less flexible languages— this has been one of the reasons to reject ALGOL 60 as a serious tool. In my opinion these people bet on the wrong horse. I don't agree with them although I can sympathize with them: if one has solved a problem one tends to get attached to it and if one likes one's solution for it, it is, of course, a little bit hard to switch over to an attitude in which the problem is not considered worth solving any more. The experience with ALGOL 60 translation has taught us still another thing. Some translator makers could not refrain from optimizing, but finding the task as such too difficult to do they tried to ease matters by introducing additional restrictions into the language. The fact that their translators had only to deal with a restricted language, however, did not speed up the translator construction: the task to exploit the restrictions to full advantage has prevented this.
번역기의 구조와 관련해서, ALGOL 60은 비최적화 번역기를 크게 알리게 되었는데 이는 ALGOL 60 언어가 사람들에게 최적화를 유도했다는 이야기가 아닙니다. 이것은 (심지어 덜 유연한 언어에서도 돌아가는) 최적화된 번역기를 만드는 방법을 아는 사람들이 ALGOL 60을 진지하게 사용할만한 도구로 생각하지 않게 된 이유가 되기도 했습니다.
그런데 내 생각에 그 사람들은 잘못된 경주마에 투자를 한 것 같습니다. 나는 그들의 생각에 공감하긴 하지만 동의하지는 않습니다. 어떤 문제를 해결한 사람은 그 해결 방법에 집착하게 될 수 있습니다. 그리고 그 방법이 마음에 들기까지 하면 다른 방법으로 문제를 해결하는 것이 가치있다고 생각을 바꾸는 것은 더 어려워집니다.
ALGOL 60의 번역과 관련된 경험으로 우리는 새로운 것을 배우게 되었습니다. 어떤 번역기 제작자는 자제하지 못하고 최적화를 시도했는데, 작업이 너무 어려워서 언어에 제약을 추가해서 문제를 좀 쉽게 만들어보려 했습니다. 하지만 그렇게 만든 번역기는 제약이 가해진 언어만을 처리하게 되었으면서도 더 빨라지지도 않았습니다. 제약 사항이라는 이점을 활용하는 작업이 오히려 영향을 준 것입니다.
Smoothly we have arrived at the third component of our tool, viz. the language: also the language should be a reliable one. In other words it should assist the programmer as much as possible in the most difficult aspect of his task, viz. to convince himself —and those others who are really interested— that the program he has written down defines indeed the process he wanted to define. Obviously the language rules may not contain traps of the kind of which there are still some in ALGOL 60, where, for instance, "real array" may be abbreviated into "array", but "own real array" may not be abbreviated into "own array". The next obvious requirement is that those rules which define a legal text don't leave any doubt as to whether a given text is legal or not, e.g. if there should be a restriction with respect to recursive use of a procedure, it should be clear under what conditions these restrictions apply, in particular when the term "recursive use" applies. I mention this particular example because here it is by no means obvious. Finally, when faced with an undoubtedly legal text we want to be quite sure what it means. This implies that the semantic definition should be as rigorous as possible. In short: we need a complete and unambiguous pragmatic definition of the language, stating explicitly how to react to any text. So much for the necessity that the tool be reliable.
이제 세 번째 구성 요소인 언어를 살펴볼 때가 됐습니다.
언어 또한 신뢰할 수 있는 것이어야 합니다. 언어는 프로그래머의 작업에서 가장 어려운 부분인, 프로그래머(자신과 관계된 다른 사람들)가 정의하고 싶었던 프로세스를 프로그램으로 작성했다는 것을 확신시키는 일에 도움을 줄 수 있어야 합니다.
ALGOL 60의 언어 규칙에서는 빠진 함정들이 좀 있다는 것은 분명합니다. 예를 들어 "real array"는 "array"로 축약하는 것이 가능한데, "own real array"는 "own array"로 축약되지 않습니다. 그리고 주어진 텍스트가 문법에 맞는지 아닌지에 대한 모호함도 제거해야 합니다. 예를 들어 프로시저를 재귀적으로 사용할 때의 제약이 있어야 한다면, 특히 "recursive use"를 적용할 때 어떤 제약 사항이 있는지에 대해 분명히 명시해줘야 합니다. 이런 예시들이 명백하지 않기 때문에 언급해 보았습니다.
마지막으로 의심할 여지 없이 문법에 맞는 텍스트가 주어진다면 그 의미가 확실하게 전달될 수 있기를 바랍니다. 즉, 의미론적 정의가 가능한 한 수준에서 최대한 엄격해야 한다는 것입니다. 간단히 말하자면 우리는 언어에 대해 완전하면서도 모호하지 않으면서도 실용적인 정의가 필요하며, 그를 통해 어떤 텍스트를 통해 어떻게 작동하는지를 분명하게 기술할 수 있어야 합니다. 그것으로 도구로서의 신뢰성을 충분히 확보할 수 있습니다.
As my very last remark I should like to stress that the tool as a whole should have still another quality. It is a much more subtle one; whether we appreciate it or not depends much more on our personal taste and education and I shall not even try to define it. The tool should be charming, it should be elegant, it should be worthy of our love. This is no joke, I am terribly serious about this. In this respect the programmer does not differ from any other craftsman: unless he loves his tools it is highly improbable that he will ever create something of superior quality.
최종적으로 나는 이 도구를 전체적으로 평가할 수 있는 또다른 품질 기준을 가져야 한다는 점을 강조하고 싶습니다. 이건 아주 미묘한 문제이고 우리의 개인적 취향과 교육받은 것에 상당히 영향받을 것이기 때문에 나는 이것을 따로 정의하지 않을 생각입니다.
도구는 매력적이어야 하고, 우아해야 하며, 우리의 사랑을 받을 가치가 있어야 합니다. 이건 농담이 아닙니다. 나는 엄청 진지하게 말하고 있습니다. 이런 측면에서 프로그래머는 다른 종류의 장인과 다르지 않습니다. 자신의 도구를 사랑하지 않는 한 더 좋은 품질의 무언가를 만들 가능성이 매우 낮기 때문입니다.
At the same time these considerations tell us the greatest virtues a program can show: Elegance and Beauty.
그리고 이런 점들을 통해 프로그램이 보여줄 수 있는 가장 큰 미덕이 드러나게 됩니다. 바로 우아함과 아름다움입니다.