Published on

[프로그래밍] 프로그래밍 언어가 여러가지인 이유

Authors
  • avatar
    Name
    Almer Minified
    Twitter

[프로그래밍] 프로그래밍 언어가 여러가지인 이유

프로그래밍 언어는 하나로 부족할까?

이론상으로는 하나의 언어로도 충분하다

이론상으로는 하나의 언어만 필요하며 보통은 어떤 언어든 상관없다. 다만 이론은 실제와 다르다. C는 버그와 신경쓸게 너무 많아 오류 없는 소프트웨어를 지속적으로 개발하기 어렵다. 그러나 정말 한 가지 언어만 배우고 싶다면 C를 선택해야 한다. C를 배우면 원하는 것은 무엇이든 할 수 있을 만큼 충분히 낮은 수준의 언어, 즉 하드웨어에 가깝다. 다시 말하면 어셈블리에 가까운 언어이다. 하지만 저수준 언어로 오랫동안 프로그래밍을 하거나 많은 사람들이 저수준 언어로 하나의 프로젝트를 해결하려 한다면 같은 내용을 반복해서 작성하고 디버깅해야 한다. 결국 생산성의 문제로 귀결된다. 이는 바람직하지 않으므로 실무자는 자주 수행되는 작업을 줄이기 위해 라이브러리를 구축할 수 밖에 없다.

라이브러리가 많아질 경우의 문제

하지만 수백 개의 라이브러리에는 저마다의 문제가 있다. 그 중 하나는 필요한 것을 찾지 못한다는 것이다. 내가 원하는 것을 찾기가 너무 어렵다. 각 프로그램마다 용도가 다르기 때문에 만들어지는 라이브러리도 다양하다. 근데 이게 언어를 어떻게 설계하느냐에 따라 만드는 난이도도 천차만별이다. 그래서 이런 경우를 접한 친구들은 이전 언어를 기반으로 하고 새로운 언어에서 공통적인 내용을 추상화해서 내재화하는 것이 유리할 것이라고 결정했다. 예를 들어 포틀란에는 일반적으로 사용되는 연산 중 예를들면 삼각 함수를 처리하는 함수가 있다. 포트란은 이런 다양한 함수가 주로 사용하기 쉽게 되어있는데 C와 마찬가지로 기계어 위에 거의 바로 구축된 언어다. 그리고나서 프로그래머들은 프로그래밍 언어의 실제 구조가 다른 프로그램의 구조와 매우 유사하여 이러한 구조를 언어의 특징으로 포착할 수 있다는 것을 깨달았고, 이것이 새로운 언어의 탄생으로 이어지게 된다. 프로그래밍 언어도 프로그램으로 인식하게 된 것이다.

상황과 우선순위에 관한 사용자의 고뇌: 먼저 등장한 절차 지향 언어

이제 상황이 흥미로워지기 시작한다. 어떤 사람들은 데이터의 가변성은 대부분의 계산에서 중요하지 않고 프로그램은 복잡할 수 있는 값을 계산해야 한다고 생각했다. 그래서 LISP와 같은 새로운 언어가 탄생하게 된다. 그리고 다 알다시피 그 결실을 맺었다. 다른 사람들은 사물을 많이 모델링하면서 이러한 사물의 속성과 동작을 C와 같은 가장 단순한 동작에서 재구성할 필요 없이 언어 수준에서 직접 처리할 수 있을지 고민했다. 이것은 매우 중요한 문제다 실제로 코딩을 해보면 추상화가 뛰어난 언어는 프로그래머에게 완전하고 일관된 정신 모델을 제공하므로 프로그래머는 기본 구현에 대해 생각할 필요가 없으며 프로그램이 조작할 수 있는 기계에 대해서도 잊어버릴 수 있다. 자바스크립트와 타입스크립트를 둘 다 사용해봤다면 이런 문제에 대해 실감할 수 있다. 이러한 언어는 또한 계산의 본질에 대해 유틸적으로 아주 편리함을 제공한다. 함수형 프로그래머는 특정 방식으로 사고하도록 언어의 안내와 영향을 받게 된다. 절차지향 언어를 사용한다면 객체 지향 언어의 개념들이 조금 낯설 수 밖에 없고 반대의 경우도 마찬가지다. 이러한 각 사고 회로는 프로그래밍 중에 의견을 교환하거나 버그를 해결해야 할 때 서로 정규화해서 인식하고 해결하는 데 도움이 된다. 이러한 다양한 사고형식이 정립된 것을 주로 패러다임이라고 한다. 한글을 이해하기 위해 고대 로마어를 이해할 필요가 없는 것처럼 파이썬이나 자바스크립트를 이해하기 위해 기계어를 이해할 필요는 없는 것이다.

객체 지향 언어의 장점

이러한 각 패러다임, 그리고 다른 많은 패러다임은 계산 가능한 모든 프로세스를 일관된 방식으로 설명할 수 있는 계산 모델이다. 이런 모든 모델에는 이전에 구축해야 했던 초기 라이브러리와 초기 프로그래밍 시도에서 얻은 통찰력이 녹아들어있다. 어셈블리어를 해봤는가? 어셈블리어에서 어려워했던 것들이 파이썬에선 한 두 줄로 끝나게 된다. 그러므로 더 높은 수준의 추상화를 설계할 수 있을수록 실무 프로그래머가 쉽고 일관되게 조작할 수 있도록 이러한 추상화를 쉽게 지원하는 컴퓨터 언어를 만들려는 인센티브가 있을 수 밖에 없다. 생산성을 높이고자 하는 프로그래머는 언어를 이용해서 해결해야 할 작업을 처리하고, 작업에 적합한 라이브러리를 가진 언어를 선택하려고 노력할 것이다. 당장 브라우저 코딩을 하는데 자바스크립트를 쓰는게 당연한 것처럼 말이다. 동적 할당에 대해 생각해 보라. C나 초기 버전의 C++와 같은 언어에서는 이러한 데이터 구조가 힙에 어딘가에 할당되도록 프로그래머가 직접 프로그램 내 어딘가에 특별히 할당해야 했다. 즉, 이런식으로 동적 할당을 사용하는 모든 프로그래머는 메모리 관리 문제를 해결해야 했다. 그만큼 업무강도가 올라간다. 자바, 파이썬과 같은 언어에서는 할당 해제가 올바르게 수행되도록 하는 동작이 자동으로 처리된다. 이렇게 하면 프로그래머는 다른 곳에 노력을 집중할 수 있게 된다.

소요되는 시간의 차이

실수로 C 프로그램에서 메모리 할당에 대한 문제를 처리하는데에 하루를 꼬박 바친 적이 있다. 수정 사항을 찾는 데 24시간이 걸렸는데 문제 해결엔 1분도 걸리질 않았다. 이런 문제가 다른 언어에선 자동으로 처리될 수도 있는 것이다. 셀레니엄과 포페터를 둘 다 사용해봤다면 패킷 처리에 있어서 셀레니엄은 정말 오래 걸리는데 반해 포페터는 아주 쉽게 내재화된 소스로 처리할 수 있음을 경험할 수 있다.

언어의 구조도 이런 내재화에 영향

파이썬은 들여쓰기를 기초로하는 문법을 가졌다. 반면에 자바스크립트는 중괄호를 이용한다. 이런 사소한 문법 하나도 전체적인 프로그램을 설게하는데에 영향을 미치고 그 영향은 그 언어에 특화된 라이브러리와 역할에 대해서까지 영향을 주게 된다.