인류의 역사를 바꾼 프로그래밍 언어

노성호·도강호 기자 2014.05.30 11:13
글자크기

프로그램 언어의 역사 재귀함수에서 C언어까지


인류의 역사를 바꾼 프로그래밍 언어


2013년 11월 발표된 세계 슈퍼컴퓨터 순위에서 1등을 차지한 중국의 톈허2(Tianhe-2)는 1초에 약 3경 3860조 번을 계산할 수 있다. 인간이 20세기 중반에 만들어 낸 계산 도구인 컴퓨터는 경이로운 계산 속도를 무기로 하여 강력한 문제 해결 도구가 됐다.
한국은 2012년 11월에 처음으로 세계 슈퍼컴퓨터 순위에 이름을 올렸다. 국산 슈퍼컴퓨터로는 처음으로 천둥이 500위권 안에 들어간 것이다. 천둥을 개발한 이재진 서울대 컴퓨터공학부 교수는 그동안 한국은 컴퓨터를 운용할 수 있는 소프트웨어(SW) 기술이 떨어져 슈퍼컴퓨터를 만들지 못했다고 설명했다.
결국 계산 능력이 아무리 뛰어난 컴퓨터라 하더라도 SW가 나쁘면 ‘돼지 목에 진주목걸이’에 지나지 않는다는 것이다. 얼마나 좋은 SW를 제작하느냐에 따라 컴퓨터의 활용도가 달라진다. 최근 주목받는 하둡처럼 새로운 SW 개발 여부에 따라 그동안 인류가 풀지 못한 문제가 한번에 해결되기도 한다.

하지만 컴퓨터의 속도가 빠르고 좋은 SW가 있어도 해결할 수 없는 문제들이 있다. 수학자들은 1930년대에 풀 수 있는 문제와 풀 수 없는 문제를 구분할 수 있는 연구를 마쳤다. 당시 수학자들은 연구를 위해 몇 가지 수학 기법을 개발했다. 이 기법들이 바로 프로그래밍 언어의 원형이다. 사실 컴퓨터도 이 프로그래밍 언어로 표현된 프로그램을 검증하는 도구를 하드웨어로 제작한 것이다.



재귀함수와 튜링머신의 만남
1931년 쿠르트 괴델은 ‘불완전성 원리’를 발표했다. 간단히 요약하면 인간이 참인지 거짓인지 알 수 없는 수학 명제가 존재한다는 내용이다. 당시 모순이 없는 완전한 수학체계를 꿈꾸던 수학자들에게는 청천벽력과 같은 일이었다. 괴델의 불완전성 원리는 수학에 모순이 없다는 명제 자체를 증명할 수 없다는 내용을 담고 있기 때문이었다.
그런데 불완전성 원리는 수학자들에게 좌절을 안긴 반면에 프로그래밍 언어가 발전하는 계기가 됐다. 괴델은 불완전성 원리를 증명하기 위해 기계식으로 계산 가능한 범위를 정의했다. 이때 기계식 계산 과정을 표현하는 ‘재귀 함수’라는 개념을 도입했다. 이 재귀 함수는 프로그래밍 언어의 초기 모습이라고 할 수 있다.
1936년 앨런 튜링은 괴델의 불완전성 원리와 계산 가능한 범위를 괴델과 다른 방법으로 정의하고 증명했다. 튜링은 증명을 위해 간단한 장치로 구성된 ‘튜링 머신’이라고 불리는 기계식 계산 장치를 정의했다. 괴델이 재귀 함수라는 표현법을 만들었다면 튜링은 튜링 머신이라는 계산 기계를 만든 것이다. 튜링은 튜링 머신을 이용해 괴델과 같은 결론에 도달했다.
그 결과 괴델의 재귀 함수로 표현된 문제는 모두 튜링 머신으로 계산할 수 있었다. 반대로 튜링 머신으로 계산할 수 있는 문제는 모두 재귀 함수로 표현할 수 있었다. 프로그래밍 언어와 이를 처리할 수 있는 기계가 만들어진 것이다. 이 때문에 튜링 머신을 현대 컴퓨터의 이론 모형이라고 한다.
한편 튜링 머신이 발표된 1936년에 수학자 알론조 처치는 람다 대수를 발표했다. 정확히는 1930년에 처음 제안했지만 오류가 있어서 수정된 체계를 다시 제시했다. 람다 대수는 수학에서 함수의 계산을 단순하게 표현하고 이해할 수 있게 돕는다. 그런데 람다 대수로 표현할 수 있는 내용은 괴델의 재귀 함수로도 표현될 수 있었다. 이렇게 1930년대에 발표된 재귀 함수, 람다 대수, 튜링 머신은 현대 컴퓨터와 프로그래밍 언어의 중요한 이론 토대를 마련했다. 하지만 현재 주로 사용되는 프로그래밍 언어는 이들과 별개로 개발된 경우가 많다.

인간이 먼저냐 컴퓨터가 먼저냐
1946년에 제작된 에니악은 계산 내용이 바뀌면 배선을 다시 해야 했다. 지금처럼 덧셈을 하는 도중에 뺄셈을 하기 위해 연산 기호를 바꾸는 것이 아니라 컴퓨터의 배선을 바꿔야 했다. 현대와 같은 SW 프로그래밍이 아니라 하드웨어(HW) 프로그래밍이었다. 하지만 계산 내용에 따라 배선을 바꾸는 방법은 시간도 오래 걸리고 복잡했다.



다소 간단한 프로그래밍이 가능해진 것은 현대 컴퓨터에 사용되는 폰노이만 구조가 컴퓨터에 도입된 다음이다. 폰노이만 구조는 저장장치에 데이터와 함께 데이터를 처리할 프로그램을 함께 기록한다. 폰노이만 구조에서는 저장장치의 내용만 수정하면 되기 때문에 프로그래밍이 간단했다.
하지만 초기 프로그래밍은 0과 1만을 사용했다. 전기신호를 사용하는 컴퓨터는 0과 1만 구분할 수 있기 때문이다. 예를 들어 한 번에 4자리 신호를 인식하는 컴퓨터를 생각해 보자. 이 컴퓨터는 ‘1111’을 ‘더하기’로 인식하도록 제작되어 있다. 컴퓨터 사용자는 ‘2+3’을 하려면 ‘0010 1111 0011’이라고 입력해야 한다. 여기서 0010과 0011은 각각 2와 3의 2진법 표현이다. 원래 2와 3의 2진법 표현은 10과 11이지만 컴퓨터가 한 번에 4자리 신호를 인식하기 때문에 4자리에 맞추기 위해 앞에 00을 붙여야 한다. 가운데 1111은 앞에서 말한 대로 덧셈 명령이다.

기계어라고 부르는 이 프로그래밍 방법은 실제로 더 복잡하고 어렵다. 사람을 위한 언어가 아니라 기계가 알아들을 수 있는 언어기 때문이다. 그래서 인간이 알아보기 쉽도록 기계어와 특정 명령을 단어를 대응시켜 ‘더하기’를 ‘1111’대신 ‘plus’로 표현하는 어셈블리어가 개발됐다.
하지만 어셈블리어를 이용해도 프로그래밍은 쉽지 않았다. 모든 동작을 일일이 지정해야 하는 컴퓨터의 특성 때문이다. 예를 들어 밥을 먹는다면 컴퓨터에 내려야 하는 지시는 다음과 같다. ‘(엄지를 움직이기 위해) 오른손 엄지 근육을 수축시켜라. (검지를 움직이기 위해) 오른손 검지 근육을 수축시켜라. (손을 숟가락으로 가져가기 위해) 어깨세모근(삼각근)과 두갈래근(이두근)은 수축시키고 세갈래근(삼두근)은 이완시켜라….’ 이렇게 모든 과정을 빠짐없이 컴퓨터에 지시해야 하고, 하나라도 빠질 경우 원하는 결과를 얻지 못할 수도 있다. 0과 1로 된 기계어로 지시를 내리는 것보다는 쉽지만 프로그래밍 언어는 여전히 컴퓨터를 위한 것이었다.

좀 더 사람을 위해 사람의 언어에 가깝게 만들어진 최초의 고급 언어는 1954년에 개발된 포트란(FORTRAN)이다. IBM은 당시 컴퓨터를 가장 많이 사용하던 과학자들의 산술계산을 돕기 위해 과학 계산용 언어인 포트란을 개발했다. 포트란은 산술계산에 특화되어 있어 이후 개발된 범용 언어들에 비해 간단하고 빠르게 프로그래밍을 할 수 있는 부분이 있어 여러 단계의 개량을 거쳐 현재도 사용되고 있다.


더 쉬워지는 프로그램 언어
포트란 개발 이전에 이미 재귀 함수나 람다 대수와 같은 프로그래밍 언어의 기초 이론 연구는 이뤄져 있었다. 하지만 포트란은 이런 이론 연구와 별개로 당장 컴퓨터 사용에 필요한 기능을 구현할 수 있도록 개발됐다.

현재 가장 많이 활용되는 언어인 C도 마찬가지다. C언어는 앞서 개발된 언어인 B를 이어 개발됐다는 의미에서 붙인 이름이다. B언어는 1969년 운영체제인 유닉스에서 시스템 프로그래밍을 하기 위해 개발됐다. 하지만 HW 발전에 따라 B언어에 몇 가지 새로운 기술상의 문제가 발생했고, 이를 보완하기 위해 C언어가 개발됐다.
C언어는 B언어가 당면한 문제들을 해결하기 위해 개발된 만큼 프로그래밍 언어의 이론 연구와 거리가 있을 수밖에 없었다. 오히려 HW와 프로그래밍 사이에서 발생하는 문제를 해결하기 위한 것인 만큼 현대 프로그래밍 언어 관점에서 보면 고급언어와 어셈블리어의 중간 정도라는 모호한 성격을 띠기도 한다.

하지만 모든 언어가 당장의 필요에 의해 개발된 것은 아니다. 프로그램의 개발과 수정 등을 더 쉽게 할 수 있는 기법이 반영된 프로그래밍 언어들이 개발됐다. 또 재귀 함수, 람다 대수 등 프로그래밍 언어 이론에 따라 개발된 언어도 나왔다. 특히 1980년대 이후로는 구조형 프로그래밍, 객체지향형 프로그래밍, 함수형 프로그래밍 등 다양한 프로그래밍 패러다임이 경합하는 상황이 됐다. 각 패러다임에 따라 다양한 언어도 만들어졌다.

프로그램의 안전성이 포인트
프로그래밍 언어는 처음 기계어에서부터 어셈블리어, 포트란, C언어 등 사람이 더 프로그래밍 하기 쉬운 상위 언어로 발전해 왔다. 그동안 제안된 여러 프로그래밍 패러다임도 프로그래밍을 더 쉽게 하기 위해 제안된 것들이다.
최근 발표되는 각 언어의 최신 형태들은 어느 특정 패러다임에 국한되지 않고 모든 패러다임을 다 담고 있는 상위의 언어로 개발되고 있다. 더 쉬운 프로그래밍을 위해 특정 기능이 있는 모듈을 레고처럼 조합해서 프로그래밍 할 수 있는 언어까지 개발됐다.

프로그래밍은 점점 쉬워지고 있지만 여전히 해결하지 못하는 문제가 있다. 안전성이다. 설계에 따라 만들어진 건물, 선박, 기계는 부품이 파괴되거나 구조가 변형되지 않는 한 안전하다. 설계가 최종 산출물의 안전성을 보장한다. 하지만 프로그램은 다르다. 오류 없이 잘 정의된 논리에 따라 작성된 프로그램이라고 해도 언제나 오류가 발생한다. 프로그램과 버그는 실과 바늘처럼 항상 함께 있는 것으로 여겨질 정도다.

하지만 프로그램이 생활 곳곳에 파고들면서 안전성 문제는 더 중요해지고 있다. 최근 미국에서는 차량 급발진 사고가 자동차를 제어하는 SW의 오류에서 비롯된 것으로 밝혀지기도 했다. 즉 SW의 오류로 발생한 치명의 결과가 확인된 것이다.
쉬운 프로그래밍과 함께 프로그램의 안전성이 최근 프로그래밍 언어 연구자들의 화두가 되고 있다. 하지만 프로그램 동작 이전에 프로그램 운용 과정에서 나타날 오류를 찾아내는 것은 여전히 어렵다. 다만 재귀 함수나 람다 대수 같은 잘 정의된 프로그래밍 이론에 따라 만든 언어는 프로그램 제작 단계에서 오류를 검출할 수 있는 도구를 일부 사용할 수 있는 것으로 알려져 있다. 물론 갈 길은 여전히 멀다. 그래도 분명한 것은 전자 기기의 활용과 프로그램의 중요성이 증가할수록 프로그램의 오류를 찾아내고 수정하는 기술, 프로그램의 안전성을 높일 수 있는 기술이 정보산업의 핵심이 될 것이라는 점이다.

[코딩] 1. 읽기-쓰기-수학, 그리고 코딩?
[코딩] 2. 프로그래밍 언어, 80년의 역사가 인류를 바꿨다

TOP