튜링상 관련 업적

실제로 사용할 수 있는 고급 프로그래밍 시스템의 설계에 기여한 바가 지대하고, 영향력이 크며, 지속적이다. 특히 포트란과 관련된 일과, 프로그래밍 언어 명세를 위한 작업의 정형화가 눈에 띈다.

1977년 튜링상 선정 이유 중에서​1​

포트란 언어

포트란은 대중화된 최초의 고급 프로그래밍 언어로 인정받고 있다. 일단, 고급 프로그래밍 언어high-level programming language라는 말에 대해 짚고 넘어가야겠다. ‘고급’이라고 이름을 붙였다는 것은, 달리 생각하면 상대적으로 ‘저급’한 프로그래밍 언어가 있다는 의미이다. 영어로 표현하자면 low-level이 될 터인데, ‘저급’으로 번역하면 좀 어폐가 있다. Low-level은 ‘수준이 낮다’는 의미라기보다는, ‘원시적’이라는 의미로 받아들이는 것이 더 적합하다. 원시적인 프로그래밍 언어로는 기계어machine language나 어셈블리어assembly language가 있다.

원시적 프로그래밍의 어려움

프로그래밍을 지원하는 컴퓨터가 처음 등장했을 때, ‘프로그래밍’이라 함은 곧 기계어 사용을 의미했다. 기계어는 기계가 곧바로 실행할 수 있는 언어였고, 0과 1의 조합으로 표현되었다. 0과 1이 어지러이 전개되는 기계어 프로그램을 보고 한 눈에 의미를 파악하기란 쉽지 않다.

0011010101101010
1001010111010101
1001110100010101
0100000011111111

예를 들어 위의 기계어 프로그램 코드를 보고, 이것이 무슨 일을 하는지 감을 잡기란 쉽지 않다. 이것을 이해하려면 각 비트의 값이 무엇을 의미하는지 알아야 하는데, 컴퓨터의 하드웨어 설명서를 뒤져야만 가능한 일이다. 그래서 초창기부터 어셈블리어가 등장했다. 어셈블리어는 기계어의 일부 이진수 조합을 인간이 이해할 수 있는 단어로 표현할 수 있게 해준다.

ADD #0101, @0110, @1010
MUL #0101, @1101, @0101
MUL #1101, @0001, @0101
JMP #11111111

위의 어셈블리 프로그램은 앞의 기계어 프로그램과 같은 일을 하지만, 훨씬 직관적으로 코드가 이해된다.​**​

하지만 어셈블리 프로그램도 이해하기가 녹록지는 않다. 각 줄이 의미하는 바는 이해할 수 있어도 여러 줄의 코드가 어떤 ‘의도’를 가졌는지를 알아내려면 상당한 주의와 시간이 필요하다. 특히나 각 줄에서 명령어 뒤에 나오는 인자들에 주목해보자. 우리가 아는 대부분의 컴퓨터들은 폰 노이만 구조를 채택하고 있다. 폰 노이만 구조의 특징은 코드와 데이터가 모두 메모리라는 기억 공간에 올라가 있으며, 이에 대한 접근은 주소address라는 숫자를 통해 이루어진다는 점이다.​5​

위의 어셈블리 프로그램에서 #이 붙어 있는 숫자는, 그 값 자체를 의미하고, @가 붙어 있는 숫자는 주소를 의미한다. ADD #0101, @0110, @1010이라는 코드는, 0101이라는 ‘값’을, 0110이라는 주소에 ‘저장된 값’과 더해서, 1010이라는 주소의 ‘메모리 공간’에 저장하라는 의미이다.​††​ @0110이나 @1010이라는 메모리 공간은 단순한 임시 저장용일 수도 있지만 최종 결과를 저장하는 공간일 수도 있다. 그 정확한 역할이 무엇인지는 프로그래머가 전체 프로그램을 이해해야지만 알아낼 수 있을 것이다.

또한, 초기의 컴퓨터 프로그램은 대부분이 과학 계산용이었다. 당시 컴퓨터를 사용한 과학 계산은 행렬을 포함한 수치 연산이라고 해도 과언이 아니었다. 행렬 데이터는 2차원 이상인 경우가 많았지만, 이 데이터가 올라가는 메모리는 1차원의 구조였다. 따라서 다차원의 구조를 1차원의 구조로 변환하는 작업이 어셈블리 프로그램 내에서 이루어져야 했는데 프로그래머들이 골치깨나 아팠을 것이다.

자동 프로그래밍

어셈블리 프로그래밍의 어려움에서 벗어나기 위해 여러 시도가 벌어졌다. 결국은 사람이 쉽게 이해하고 작성할 수 있는 프로그래밍 언어를 만들려는 노력이었다. 당시는 이런 프로그래밍을 자동 프로그래밍automaic programming이라고 불렀다.​‡‡​ 대표적인 사례가 그레이스 호퍼​6​, 앨런 펄리스​7​ 등의 노력을 들 수 있다. 하지만 결과물은 인상적이지 못했다. 그레이스 호퍼가 만든 언어는 기계어로 변환하는 데 시간이 오래 걸렸고, 변환되어 나온 기계어 프로그램은 속도가 너무 느렸다. 앨런 펄리스가 만든 언어는 일부 수식 계산만 지원했으므로 현장에서 사용하기에 부족함이 많았다. 이런 와중에 공개된 포트란은 이 두 가지 단점을 해소해주어서 많은 관심을 받았다.

포트란의 첫 버전은 1956년에 공개되었다. 첫 버전은 부족한 점이 많았지만, 메모리 주소를 직접 다뤄야 하는 불편함을 없애주었고, 반복문loop을 지원했다.

10   DO 12 I = 1, 100
11   IF(ARG-VALUE(I)) 12, 20, 12
12   CONTINUE
20

위의 코드는 포트란 첫 버전의 프로그래머 참고 설명서에 나오는 예이다.​8​ 요즘 사용되는 프로그래밍 언어, 예를 들어 C언어를 써서 같은 일을 하는 코드를 작성하면 아래와 같다.

for (i=1; i<=100; i++) {
    if (ARG-VALUE[i] == 0) break;
}

일단, 변수들에 주목해보자. 위의 포트란 코드에서 변수는 I, ARG, VALUE 세 가지가 있다. 변수란 무엇인가? 메모리에 저장되어 있는 데이터이다. 만약 기계어나 어셈블리어로 작성했다면 실제 메모리 주소를 사용했어야 한다. 하지만 포트란에서는 이제 메모리 주소를 직접 다루지 않아도 된다. 이 변수가 위치한 메모리의 주소는 컴파일 과정에서 결정된다.

VALUE 변수는 특별하다. 왜냐하면 배열을 표현하기 때문이다. 포트란 이후로 거의 모든 프로그래밍 언어는 배열을 지원한다. 포트란 첫 버전에서는 최대 3차 배열까지 허용했다.

다음은 반복문이다. 위의 코드가 하려는 일은 VALUE라는 배열의 첫 번째 값에서부터 100번째 값 중, 몇 번째 것이 ARG라는 변수에 있는 값과 같은지를 찾는 것이다. 포트란 코드를 보면 DO라는 반복문이 어디까지를 포함하는지 명시적으로 나타내기 위해 12라는 숫자를 지정하고 있다. 즉 12라는 라벨label이 붙어 있는 코드까지가 반복문에 포함된다는 의미이다. 이렇게 한 이유는 당시에 아직 블록block 혹은 복합문compound statements이라는 개념이 정립되지 않았기 때문이다. 알골 언어에서 복합문이 등장했고, 이때부터 중괄호 혹은 BEGIN END라는 예약어를 사용하여 반복문이 적용되는 코드의 범위를 표시할 수 있게 되었다.

마지막으로 비교문을 보자. IF라는 비교문은 비교 결과에 따라서 3가지 선택지를 가진다. 위의 예에서는 12, 20, 12로 표현된다. 각각은 수행할 코드가 있는 라벨label을 나타낸다. 일반적으로 현대의 프로그래밍 언어에서 IF는 두 가지 선택지를 제공한다. 비교 결과가 ‘참’인지 ‘거짓’인지를 따진다. 하지만 포트란 첫 버전에서는 비교 결과가 숫자라고 보았다. 그래서 결과값이 ‘0보다 작을 때’, ‘0과 같을 때’, ‘0보다 클 때’의 세 가지 경우로 나뉘었고 각각의 상황에서 수행되어야 할 코드가 있는 위치 라벨을 명시했다. 위의 포트란 코드에서는 ARG에서 VALUE(I)를 뺀 값이 0이면 20이라는 라벨이 붙은 코드를 수행하고 그렇지 않은 경우에는 12라는 라벨이 붙은 코드를 수행하게 된다. 그렇다면 왜 포트란은 이렇게 3가지 선택지를 제공했던 것일까? 그 이유는 포트란 첫 버전이 기반했던 IBM 704 모델의 구조 때문이었다. IBM 704 모델의 기계어가 이렇게 3가지 선택지를 제공했기 때문에 거기에 맞춰서 언어를 설계했다고 한다.​9​

포트란의 발전

발표되었을 때 관심을 끌기는 했지만, 포트란 첫 버전에는 결정적인 단점이 있었다. 서브루틴을 지원하지 않았다. 1958년에 두 번째 버전이 발표되면서 서브루틴이 지원되었다. 이때부터 사용자들의 관심이 증가하기 시작했고 IBM은 본격적으로 포트란을 확산시키려는 노력을 기울였다. 1961년에 IBM은 네 번째 버전 개발을 시작했다. 이때부터는 존 배커스가 관여하지 않았다. 1962년에 포트란 IV가 IBM 7030 용으로 발표되었고 이어 IBM의 다른 모델에서도 속속 지원되었다.

포트란이 큰 인기를 끌면서 사용자들이 IBM 컴퓨터를 선호하는 경향이 나타났다. 위기감을 느낀 경쟁사들은 자사의 컴퓨터에 포트란 컴파일러를 제공하기 시작했다. 포트란 언어는 꾸준히 개선되었고 표준화가 이루어졌다.

포트란은 현대의 프로그래밍 언어에 비하면 유연함을 떨어지지만 과학 계산을 위한 수치 연산용으로는 탁월한 효율을 보여주었고, 단순한 구조로 인해 병렬처리에 적합하여 슈퍼컴퓨팅용으로 많이 사용되었다.

포트란 언어가 등장한 시기는 모니터 터미널이나 자기 디스크가 프로그래밍 용도로 사용되기 전이었다. 그래서 펀치 카드에 코드를 기록했으며 그러다 보니 포맷에 제약이 있었다. 포트란 코드 한 줄당 펀치 카드 한 장이 사용되었다.​§§​

1 2 3 4 5