이 세상에는 수없이 많은 프로그래밍 언어들이 있고 각자의 영역에서 유용하게 사용되거나 아니면 범용적으로 뭐든지 가능한 프로그래밍 언어들로 나눠지는데 두 그룹의 목적이 서로 다르니 그 어떤 프로그래밍 언어가 등장해도 완전한 통합은 불가능하다는게 큰 문제임. 예를 들어 운영체제/시스템 프로그래머가 웹 쪽으로 확장하려고 하면 C 언어를 그대로 사용하긴 어렵고 그 반대도 마찬가지이지. 결국 모든 프로그래밍 언어들은 하나로 통합되지 않고 각자의 영역에서 사용되거나 범용적으로 사용되는 지금의 양상을 그대로 유지하게 될 거라고 예측함.


디어 에스더에서나 볼법한 시(C가 아닌 문학적인 의미에서 시)는 걷어내고 본문으로 들어가자면 내가 사용하는 프로그래밍 언어들(사실상 C 원툴이지만)에 대해 느끼는 공통적인 불만점이 상당히 많음. 그것은 문법 구조로 해결할 수 있는 부분들도 있고 아예 언어 설계적인 측면에서 잘못되었다고 보는 것도 있음. 그런 불만들을 신세한탄식으로 풀어볼려고 함.


1. 문법 관련 불만점들

(1). 문법에 예외 규칙이 상당하다.

가장 큰 불만은 C에서 두드러지는데 통일된 몇가지 규칙이 있긴 하지만 극소수이고 대부분은 상황에 따라 달라진다. 일단 lvalue, rvalue 규칙들이 많은 불만 사항중에 하나. 예시로 거의 대부분의 프로그래밍 언어들은 수식에서는 다 똑같다. =를 기준으로 왼쪽은 객체(또는 대상체) 오른쪽은 객체 또는 값이 올 수 있음. 반대로 말하자면 우항에 있는 계산 결과가 좌항에 저장된다고 볼 수 있음. 그런데 대부분의 언어에서 글을 읽는 방향과 좀 차이가 있다. 보통 왼쪽 위부터 오른쪽 아래로 읽어나가는데 다른 구문들은 그렇게 읽히지만 수식만 예외적으로 우항을 먼저 읽고 좌항에 그게 저장되는 논리로 생각해야 함. 단순 스타일적인 문제로만 치부하기에는 거리가 멀다. (원래 내가 사용하던 중괄호 스타일은 Allman 스타일이였지만 협업 프로젝트를 한번 진행해보고 나서부터는 바로 K&R 스타일로 바꾸었던 적도 있을 정도로 스타일에 민감하지 않음.) 내가 스타일에 민감하지 않았는데 수식을 읽는 순서는 좀 이상하다고 생각이 든다.


(2). 세미콜론의 문제점.

다행히도 세미콜론은 통일된 규칙이 있어서 어렵지 않게 이해할 수 있다. 이 규칙을 제대로 설명해주지 않는 책이 많아서 문제이지만. if, while 등의 구문들은 소괄호로 둘러싸인 조건 수식이 오고 난 뒤에는 반드시 수식이 와야한다. 그래서 세미콜론이 붙는 것임. 중괄호로 둘러싸인 블록이 오는 것은 세미콜론을 쓰지 않아도 되는 이유는 중괄호 자체가 수식의 범위를 표현해주기 때문에 없어도 되는 것. 그런데 참 어이없게도 예외가 하나 존재한다. 함수와 사용자 정의 타입들. 둘다 중괄호 수식만을 인정하지만 함수는 세미콜론으로 끝나지 않는 중괄호고 사용자 정의 타입들은 무조건 중괄호로 끝나야 한다. (타입 선언의 경우에는 세미콜론으로 끝나는 중괄호가 아니라 그냥 수식이지만 중괄호가 들어가는 정의 수식부터 문제가 생김. 이걸 모르고 메인 함수 앞에 구조체 선언을 하고 세미콜론으로 끝내지 않으면 함수가 종료할때 문제가 생길 가능성이 높다.) 아예 세미콜론을 사용하지 않거나 최소한 통일된 규칙을 제공하였으면 좋지 않았을까?


(3). 포인터와 배열.

내가 지금까지 읽어왔던 설명중에서 포인터와 배열을 표준에 맞으면서 쉬운 설명을 본적이 없다. 사실 나도 이 두 타입에 대해 제대로 설명하지 못한다. 그 만큼 초보자에게 큰 장벽이라는 뜻. 문제는 초보자가 아니라 고수도 가끔 포인터나 배열을 잘못 사용해서 프로그램을 강제종료시키거나 의도치 않은 동작을 하는 경우가 상당히 많다는 것임. 그것은 포인터와 배열에 대해 심도있는 이해를 한다고 해결이 되는게 아니라 그냥 C 스타일의 포인터와 배열은 위험성을 가지고 있는 문법이다.


사실 포인터와 배열은 하드웨어에 둔한(혹은 덜 민감한) 방식이라고 생각하기에 위험하기도 하고 불편하다고 생각해본 적이 있음. 어떤 기계가 항상 동적 메모리 할당을 지원하는 것도 아니고 정해진 데이터 영역만 써야하는 경우가 많은데 배열은 이 고정적인 데이터 영역을 사용하는데 편하고 포인터는 메모리 할당을 지원하는 기계에서 사용하기 편하다는 점. 그리고 결국 배열은 포인터로 추상화될 수 있고 둘이 비슷하게 취급될 수 있다는 점이 하드웨어에 대한 부담을 덜어준다고 생각함.


(4). 문자와 문자열의 차이.

문자는 대응되는 값을 가진 하나의 문자, 문자열은 문자가 연속적으로 할당된 공간의 첫번째 요소를 가리키는 대상체라고 가르치는 책이 많았다. 틀린건 아니지만 좀 이해하기 어렵다. 문자가 저장된 대상체가 널 문자를 포함할 수도 있고 이게 메모리에 저장되면 바이트 순서에 따라 다르겠지만 문자열이 되는 경우가 상당하다. 그리고 문자열에 널 문자가 없으면 문자열로 취급되지 않는다. 또 포인터와 배열에 대입하는 문자열이 다르다는 점도 초보자가 이해하기 어렵다.


(5). 블록 구조로 인한 문제점들.

한 블록 안에서 변수가 선언될때 바깥에 있는 같은 이름의 변수가 이미 존재하면 바깥에 있는 변수는 숨겨지는데 이 규칙이 애매하다. 전역 변수를 함수 안에서 선언된 변수로 가릴 수 있고 그게 안되고 오류를 출력하는 경우도 있다는게 문제점.


글자수 제한 때문에 여기까지만 설명하고 언어 설계상 잘못된 부분들은 다음에 또 작성해볼 생각임.