0. 개요
프로그래밍 언어론에 대한 깊은 이야기를 하기 전에
간단하게 들어가기에 앞서 프로그래밍의 역사와 진화에 대한 내용을 알아보자.
(재미로 읽어보자)
1. 초기
과거의 프로그래밍은 상당히 무식한 방식이었다.
컴퓨터는 매우 거대한 장치였고, 프로그래머들은 비교적 저렴했다.
오히려 비싸다고 생각했는데, 아직 기술 초기 단계였고, 프로그래머들의 능력과 고급 기술은 그리 필요하지 않았기 때문이란다.
프로그래밍을 할 때에는 Machine Language(컴퓨터의 CPU를 직접 제어하기 위한 0과 1의 비트로 이루어진 코드)를 사용했다.
이를 통해 덧셈, 비교, 데이터 이동 등과 같은 기본 연산을 컴퓨터에게 지시할 수 있었다.
한 예를 들어, 두 정수의 최대공약수(GCD)를 계산하는 프로그램을 만들 때, x86 명령어로 아래와 같이 표현될 수 있다 :
55 89 e5 53 83 ec 04 83 e4 f0 e8 31 00 00 00 89....
2. 다음 단계
다음으로 Assembly Language로 코딩하는 단계로 넘어갔다.
어셈블리 언어는 기계어에 비해 사람이 이해하기 쉬운 mnemonic abbreviations (니모닉 약어)를 사용하여 작성된다.
이것도 GCD를 계산하는 프로그램으로 예시를 들어보자 :
pushl %ebp
movl %esp, %ebp
pushl %ebx
subl $4, %esp
andl $-16, %esp
call getint
movel %eax, %ebx
call getint
cmpl %eax, %ebx
je C
A: cmpl %eax, %ebx
jle D
subl %eax, %ebx
B: cmpl %eax, %ebx
jne A
...
# Assembly Language 란?
- 명령어와 기계어 간에 일대일 대응 관계를 가지며, 어셈블러(Assembler)라 불리는 프로그램을 통해 기계어 명령을 번역한다.
- 이러한 어셈블리 언어는 일반적으로 명령어와 머신 코드 간에 직접적인 대응 관계를 가지므로 컴퓨터의 아키텍처에 따라 다양한 어셈블리 언어가 존재한다.
- 매크로 확장(Macro Expansion)을 지원하는 경우가 많다.
- 이를 통해, 일반적인 명령어 시퀀스에 대한 매개변수화된 약어를 정의할 수 있다.
- 이렇게 하면 반복적인 작업을 단순화하고 코드의 가독성을 높일 수 있다.
아무리 기계어에 비해 편해졌다 한들, 여전히 어려우며 컴퓨터 중점의 언어이다. 또한 이식성이 낮다.
3. machine-neutral programming languages의 목표
특정 컴퓨터 아키텍처나 기계에 관계없이 사용할 수 있는 프로그래밍 언어의 필요성을 느끼고 이러한 목표를 가진 언어들이 등장했다.
그중에서도 수치 계산 능력을 가진 언어로 Fortran이 유명하다. ( 타 OS 끼리의 호환이 가능했다.)
4. 고급 언어의 등장
Lisp와 Algol와 같은 고급언어가 탄생하기 시작했다.
고급 언어는 자연어와 비슷한 수준의 언어를 말한다.
그렇다면, 자연어와 어셈블리어 간에 변환은 누가 했을까?
물론 "compiler"의 몫이다.
컴파일러는 어셈블러보다 복잡하며, 고수준 언어와 저수준 언어 간에 1:1 대응 관계가 없어서 번역 작업이 더 복잡하다.
5. 기술의 발전
기술 발전과 컴파일러의 최적화로 인해 성능 차이는 점점 좁혀졌고,
프로그래머보다 컴파일러의 성능이 더 좋아지는 역전 상황이 벌어졌다.
6. 프로그래머 노력 경제화
말이 어려운데, 프로그래머의 역량과 노력량이 곧 돈이 되는 시대가 되었다는 것이다.
현재는 프로그래머의 노력이 프로그램의 초기 작성뿐만 아니라 유지보수, 개선 및 수정에도 많은 비중을 차지하게 되었다.
결국엔 노동 비용이 컴퓨팅 하드웨어 비용을 능가하게 되었다.