Programming Language History
프로그래밍 언어의 역사
제 1세대 언어 : 어셈블리 언어
제 2세대 언어 : 비 구조적 고급 언어
제 3세대 언어 : 프로시저 위주 고급 언어 (Pascal, C)
제 4세대 언어 : 특수 목적 언어*
제 5세대 언어 : 초고급 언어** (Prolog, SETL)
* 제 4세대 언어 (특수 목적 언어)
- DB 시스템을 제어하기 위해 만들어진 명령어에서 출발했다.
- Editor, Debugger, Word Processor, Control Utility(제어용 유틸리티)과 같은 개발 도구들에 포함되는 경우가 흔했다.
- PL 설계 이론에 공헌한 바는 작지만 실용성이 크다는 특징이 있다.
ex) SQL, Lotus, Delphi, Visual Basic, Visual C++, Power Builder 등
** Specification Language (명세 언어)
- 사용자가 원하는 바를 기술하면 시스템이 요구 사항을 자동으로 구현해주는 이상적인 개념의 언어이다.
- 1979년 Winograd의 명세 언어에 대한 견해에서 현재 제 5세대 언어가 지향하는 바와 일치한다는 것을 확인할 수 있다.
1. 기원전 - 최초의 Algorithm
- BC 1500 - 3000년대, 메소포타미아(바그다드 근처)에서 발견된 형판에는 그들이 60진법 체계와 부동 소수점 표기등을 이용하여 산술 연산과 대수 방정식의 해를 계산하는 알고리즘을 사용했던 것이 기록되어 있다.
- BC 300년, Euclid(유클리드)의 저서 <Elements>에는 최대 공약수를 계산하기 위한 알고리즘이 기술되어 있다.
2. 1800년대 - Charles Babbage의 Difference Engine
Difference Engine
- Finite Difference(유한 차)의 원리(계산기와 비슷한)를 기반으로 설계된 기계이다.
- Analytical Engine의 구현에 실패하여 비교적 성능이 뒤쳐지는 Difference Engine을 기반으로 한 기계가 개발되었다.
Analytical Engine
- 몇 가지 특성을 제외하고, 현 디지털 컴퓨터와 유사한 구조의 기계이다.
- 현재 구조와 달리, 프로그램, 데이터를 주기억장치에 저장시키는 개념 없이, 연산카드, 변수카드를 이용해 저장하는 방식이었다.
- 구현의 어려움으로 인해, 실제로 개발되지는 못했다.
※ Babbage의 조수 Ada Augusta(최초의 프로그래머)의 '알고리즘 분석'에 대한 견해에서, 그 당시의 프로그래머들도 최적화 개념을 갖고 있었음을 알 수 있다.
3. 1930년대 ~ 1940년대 - 프로그래밍 표기의 급증
- 창조적인 프로그래밍 표기가 급격히 증가했던 시기로, 실제 컴퓨터에서 사용되지 못할 이론적인 것들도 다수 있었다.
- Zuse의 \(\texttt{Plan Calculus}\)
- Turing의 \(\texttt{Turing Machine}\)
- Church의 \(\texttt{Lambda Calculus}\)
- Aiken의 \(\texttt{Mark I}\)
- Von Neumann의 \(\texttt{Flow Diagrams}\)
4. 1950년대 - 최초의 High-Level PL 등장
- 1950년대 중반, IBM사의 John Backus 팀의 Fortran(FORmula TRANslation)이 최초의 고급 언어로써 등장했다.
- 출시할 당시에는 과학적 계산을 위해 고안되었으며, 이후에도 과학적 응용분야에 이용되거나 다목적 프로그래밍을 위해 다른 언어의 특성을 추가한 버전으로 업데이트 되고 있다.
- Fortran 컴파일러가 생성한 기계어 코드는 사람이 직접 코딩한 기계어 코드보다는 덜 효율적이었지만, 프로그램 작성 속도 측면에서의 효율성이 이를 커버할 수 있었기 때문에 기계어 코딩에서 고급 언어를 통한 코딩으로 패러다임이 바뀌었다.
- Fortran의 배열, 반복 구조, 분기문, 서브프로그램 등의 특성을 이후 언어에도 큰 영향을 미쳤다.
※ 1950년대 초, 기계어를 대체할 어셈블리어가 개발되었지만, 어셈블리어 또한 기계 의존적이며 자연어와의 괴리감으로 인해 고급 언어보다는 저급 언어로 분류되는 경향을 보인다.
5. 1950년대 후반 - Von Neumann 모델을 탈피한 PL이 등장
A. COBOL (Common Business-Oriented Language)
- 미 국방성에서 개발된 고급 언어로, 사용자들이 쉽게 읽고 이해하는데에 초점을 맞췄다. (이 때문에 문법이 복잡한 편에 속한다.)
- 레코드 구조, 자료 구조와 실행 부분의 분리, 출력 양식의 가변성과 같은 특징들이 있다.
- 위 특징들은 후에 DB언어에도 도입된 기능들이다.
B. ALGOL 60 (Algorithmic Language 60)
- 알고리즘을 기술하기 위한 일반적인 표현 언어로 연구, 실질적 응용 목적으로 제작되었다.
- Free-Format, begin-end Block, Recursion, Call by Value 구조적 명령문, 변수의 타입 선언, 매개 변수 등의 개념들이 도입되었다.
- 블록 구조의 언어를 위한 스택 기반 실행 환경이 도입되었다.
- BNF(Backus-Naur Forms)가 처음으로 사용된 언어이다.
C. Lisp (List Processor)
- 일반적인 리스트 구조와 함수의 적용을 기본 원리로 채택한 언어이다.
- AI분야에 응용되고 있다.
- S-expression이라는 단일 자료 구조를 이용하며, 기본적 계산의 표기 방법으로 함수를 적용한다.
- Garbage Collection 기능을 통해 사용되지 않는 메모리를 자동으로 재생한다.
- Recursion 기능이 처음으로 도입된 언어이다.
- Von Neumann 구조와는 매우 다른 연산 방식으로 인해 기존의 컴퓨터에서는 실행이 어려웠고, 이로 인해 새로운 컴퓨터 구조가 설계되거나 많은 의사 결정 시스템들이 Lisp로 작성되었고, 이는 번역 기술, 실행 속도 등의 발전에 기여했다.
D. APL (A Programming Language)
- IBM에서 배열, 행렬을 포함하는 수학적 연산을 쉽게 프로그래밍 하기 위해 개발되었다.
- 제어 구조가 없고, 특정 터미널에만 있는 그리스 기호를 사용하기 때문에 범용성이 떨어진다.
- APL로 작성된 프로그램은 대체로 이해하기가 힘든 편에 속한다.
6. 1960년대 - PL의 폭증
- 특별한 환경, 영역을 위한 특수 목적 언어들이 개발되기 시작했다.
- 이 시기에 개발된 대부분의 언어는 소멸되었으나, 소수의 언어는 PL의 발전에 지대한 공헌을 하기도 했다.
A. PL/I (Programming Language One)
- IBM에서 자사의 컴퓨터 IBM 360에 사용하기 위해 고안했다.
- Fortran, Cobol. Algol 60의 장점들과 Concurrency(병행성), Exception Holding(예외 처리), 기억장소 할당 기법등을 추가했다.
- 하지만, PL/I 번역기로의 코드 작성은 쉬운 편이 아니었고, 여러 가지 언어의 특성을 통합한 것이 충돌을 초래해서 실행 효율이 저하되고 오류 발생 빈도(신뢰성 저하)가 높아서 실패작이라 평가받고 있다.
B. Algol 68
- 일반적인 Type System(데이터형)이 처음으로 도입된 언어이다.
- Orthogonality(직교성)을 띄는 언어로, 서로 다른 두 특징이 서로 영향을 미치지 않는 구조이다.
- 이론적으로 일관성을 갖는 구조, 파일 시스템, 실행 환경 측면에서 우수하다는 평가를 받았다.
- 범용 컴퓨터에서의 사용이 매우 어려웠다.
- 후에 Algol 68에서 파생된 언어들을 Algol-Like Language(Algol 계열 언어)라고 한다.
C. Snobol (StinNg Oriented SymBOlic Language)
- 문자열 처리 기능을 최초로 도입한 언어이다.
- Snobol4 에서는 복잡하고 강력한 Pattern-Matching 기능을 제공하고 있다.
D. Simula 67
- Simula를 기본으로 하고, 거기에 Algol 60의 기능들을 포함시킨 언어이며, 시뮬레이션을 위해 설계되었다.
- 최초의 객체 지향 언어로서 Class 개념을 최초로 도입하여 객체 개념과 데이터 추상화 개념을 정립했다.
E. Basic (Beginers All-purpose Symbollic Instruction Code)
- 새로운 Time Sharing(시분할) 시스템을을 위해 간결히 설계된 언어에서 시작했다.
- 쉬운 언어 구조로 인한 무분별한 개정이 진행되어, 많은 언어 군(A Family of Language)이 존재한다.
- 2개의 ANSI의 표준화 버전(minimal Basic, Standard Basic)이 존재한다.
- Standard Basic에서는 제어 구조, 변수 선언문, 프로시저 등의 기능이 추가되었지만, 초기 Basic의 간결성으로 인해 아직까지도 초기 Basic이 교육용, 마이크로컴퓨터 응용 분야에서 이후 버전보다 널리 사용되고 있다.
7. 1970년대 - 간결성과 일관성을 추구한 PL
- 이 시대에 나온 Pascal과 C언어는 특유의 간결함과 일관성으로 인해 현재까지도 인기 있는 PL이 되었다.
- 1970년대 중반에 나온 언어들은 공통적으로 Data Abstraction, Concurrency, Verification(정확성 증명)과 같은 메커니즘들을 집중적으로 시도했다.
A. Pascal
- Algol의 개념을 계승한 언어이다.
- 작고, 간결하고, 효율적이며 구조적이다.
- 분리 컴파일, 문자열 조작, 입출력 기능 등의 주요 기능을 생략했음에도 여러 분야에서 성공했다.
B. C 언어
- Pascal과는 다른 측면에서의 간결성을 보이는 언어이다.
- Expression 위주의 Data Type 시스템을 통한 복잡성과 실행 환경을 축소하여 H/W 접근에 용이하도록 설계되었다.
- 위의 이유로, C언어는 중급 프로그래밍 언어라 부르기도 하며, Embedded System 개발에 적합하다.
- C언어와 Bliss, Forth와 같은 언어들을 이용하여 OS 프로그래밍에 사용되기도 했다.
- Linux의 전신인 UNIX 또한 C언어로 작성된 OS이다.
C. CLU
- 추상화 메커니즘을 위한 일관적인 접근 방식을 구현하기 위해 개발된 언어이다.
- CLU의 추상화 메커니즘은 데이터 추상화(cluster), 제어 추상화(iterator), 예외 처리(Ada와 비슷한 구조)이다.
- CLU의 cluster는 Simula의 class 구조와 비슷하다.
D. Euclid
- Pascal의 Aliasing(이명) 현상을 개선하고, 데이터형의 추상화, 프로그램 Formal Verification(형식 검증) 등의 기능을 추가한 언어이다.
E. Mesa
- Pascal과 비슷한 언어에 모듈 구조, 예외 처리, 병행성, 병렬 프로그래밍 등의 개념을 통합시킨 언어이다.
- OS와 같은 시스템 프로그래밍에 적합하다.
- Mesa의 모듈 구조는 후에 Modula-2의 매커니즘 고안에 영향을 끼쳤다.
8. 1980년대 - 함수형 PL, 논리형 PL의 등장과 객체 지향 언어의 발전
- Simula 67의 class 개념을 기본으로 한 객체 지향 언어들이 대거 탄생했다.
A. Ada
- 데이터 추상화, Type 메커니즘(package), 병행 처리(task), 예외 처리 등의 기능이 도입된 언어이다.
- 섬세한 설계와 미국의 지원으로 인해 보급이 느린 편이었음에도 사용자가 급증했다. (Ada는 미 국방성에서 개발되었다.)
- 큰 규모와 복잡함으로 인해 PL/I의 수순을 밟을 것이라는 예견도 있었다.
B. Modula-2
- Pascal 구조의 결점을 보완하고 추상화, 부분적 동시 처리 개념 등이 추가된 언어이다.
- Embedded 프로그래밍 목적으로 H/W 접근에 용이하게 설계된 다목적 언어이다.
- Pascal과 같이 간결성을 위해 예외 처리와 같은 몇몇 기능들을 제외시켰다.
C. Scheme
- Lisp를 개정한 버전으로 보다 획일적이고 Lambda Calculus와 비슷하게 설계된 언어이다.
D. Common Lisp
- Lisp가 표준으로 규정된 버전이다.
E. ML (Meta Language)
- 앞서 개발된 함수형 언어와는 상이한 구조를 갖고, 문법은 Pascal과 비슷한 언어이다.
- Pascal과 비슷하긴 하지만, 문법과 Type Checking 기능 등은 Pascal보다 더 유연한 구조를 갖고 있다.
F. Miranda
- 영국 맨체스터 대학의 David Turner가 개발한 언어로, ML과 연관이 깊다.
G. Prolog
- 논리형 언어로, 현재 AI분야에서 많이 활용되고 있다.
- 일본의 제 5세대 프로젝트의 주요 언어로 선정되면서 많이 알려졌다.
H. SETL
- 집합론을 PL로 구현하기 위해 개발된 언어이다.
- 미적분, 이산 수학의 교육용으로 사용되지만 구현이 어려워 많은 인기를 얻지는 못했다.
I. Smalltalk
- 일관된 객체 지향 언어의 순수한 모범 케이스가 되는 언어이다.
J. C++
- C언어의 개념을 확장시킨 객체 지향 언어이다.
K. Eiffel
- Pascal과 비슷하면서 일관성 있게 설계된 객체 지향 언어이다.
9. 1990년대 - Web PL
- 응용 문제를 빠르게 구현할 수 있고, 실 사용자가 직접 프로그래밍 가능하며, DB를 다룰수 있는 제 4세대 언어가 대두되었다.
A. sh (shell)
- 파일 관리, 파일 필터링 등과 같은 유틸리티 함수를 수행하는 시스템 서브프로그램의 호출들로 해석되는 명령들의 집합에서 시작된 웹을 위한 스크립트 언어이다.
- 변수, 제어문, 함수 및 다양한 다른 특징들이 추가되어 스크립트 언어 또한 완전한 PL이 되었다.
B. Perl
- sh와 awk(둘 다 스크립트 언어이다.)가 결합된 형태의 스크립트 언어이다.
- WWW이 널리 이용됨에 따라 CGI(Common Gateway Interface) 프로그래밍에 이상적이었던 Perl의 사용량이 급증했다.
C. JavaScript
- 웹 서버, 웹 브라우저에 사용하기 위해 개발된 스크립트 언어이다.
- 대부분 클라이언트 측 스크립트 언어로 사용하기 때문에 JavaScript 코드는 HTML 문서 내에 포함되어 있는 구조를 보인다.
- 웹 브라우저가 문서를 디스플레이 할 때, 문서에 포함된 JavaScript 코드를 해석하게 된다. (동적 HTML 문서를 생성)
- ECMA에서 ECMA-262로 표준을 확정짓고, 후에 ISO에서 이를 ISO-16262로 재확정지었다.
- Java와 달리, 상속, 메서드에 의한 메서드 호출과 같은 동적 바인딩을 지원하지 않는다.
- DOM(Document Object Model, HTML 문서의 계층적 모델)과 일치하는 객체 계층구조가 정의되어 있어, HTML 문서의 원소들에 대한 동적 제어 기반을 제공한다.
D. PHP
- 웹 응용 프로그램을 위해 HTML에 내포되는 서버 측 스크립트 언어어다.
- 개방 소스 제품으로 개발 및 배포되고 있다.
- JavaScript와 유사한 문자열, 동적 타입 배열 구조를 가지며, HTML 문서에 포함된다는 공통점이 있다.
- PHP의 배열은 JavaScript의 배열과 Perl의 Associative Array(연상 배열)가 혼합된 형태이다.
- PHP는 HTML이 요청한 브라우저에 전달되기 전에 서버에서 해석된다.
- 다양한 DB 관리 시스템을 지원하여 DB에 대한 웹 접근을 필요로 하는 프로그램 개발에 적합하다.
※ Perl, JavaScript, PHP는 범용 PL로 설계되진 않았으나, 추후 주요 PL들에 영향을 미치게 되었다.
E. Java
- C++보다 높은 정도의 단순성, 신뢰성을 제공한다.
- 많은 분야에서 응용되지만, 대표적으로 Web 개발에 가장 활발히 이용된다.
- 기본 데이터형으로 Scala Type(정수, 부동소수점, 불리언, 문자 등)을 제공한다.
- Java의 배열은 미리 정의된 클래스 객체로 제공되는 방식이다. (C++과 대조적이다.)
- 오류를 초래하기 쉬운 포인터 기능이 삭제되고, 참조(메모리가 아닌, 객체를 지시)를 사용한다.
- 제어식에 산술식을 사용할 수 없고, 레고드형, 공용체, 열거형 등을 지원하지 않는다.
- 서브프로그램 기능을 제공하지 않고, 모든 서브 프로그램은 클래스에서 메서드로 정의되어야 한다.
- 기보적으로 단일 상속만을 지원하며, 다중 상속은 Java의 인터페이스 구조를 이용하여 변칙적으로 사용할 수 있다.
- \(\texttt{synchronize}\) 수정자를 통해 단순한 형태의 동시성 제어를 제공한다.
- Thread(동시성 프로세스)를 생성하기가 쉽고, 스레드는 모든 스레드의 기초 클래스인 \(\texttt{Thread}\)로 부터 메서드를 상속받고, 모든 메소드로 그 실행이 시작, 유보, 재개, 중단될 수 있다.
- Heap으로 부터 배당된 객체(동적 할당된 객체)가 수명을 다했을 때, 자동적으로 메모리를 반환하는 기능인 Garbage Collection 기능을 지원한다.
- 암시적 데이터형 변환은 Widenning(확대 변환, \(\texttt{int} \to \texttt{float}\))만을 허용하며, 데이터형 변환을 명시적으로 진행할 경우, Narrowing(축소 변환)도 가능하다.
- 고급 언어 형태와 기계어 사이의 중간 코드 형태를 제공함으로써 이식성을 높혔다.
- Java의 Applet은 웹 클라이언트 측에서 실행되는 작은 프로그램으로, 디스플레이 중인 웹 페이지에서 HTML로 표현된 애플릿이 호출될 경우 실행된다.
- 애플릿의 중간 코드 형태인 Byte Code가 클라이언트 측에서 인터프리터로 실행되어 그 결과를 해당 웹 페이지에 출력하게 된다. (바이트 코드 또한 중간 형태 언어로 이식성을 제고시키는 역할을 한다.)
10. 2000년대 - C#과 마크업 언어
A. C#
- C++, Java에 기반한 범용 프로그래밍 언어이다.
- 컴포넌트 기반 S/W 개발과 .NET Framework 플랫폼*에서의 개발을 위해 설계된 언어이다.
B. XLST (eXtensible Stylesheet Language Transformations)
- 마크업/프로그래밍 하이브리드 언어이다.
- XML 문서의 디스플레이를 위해 XSLT로 변환하여 프로그래밍과 유사한 연산의 형태로 바꿀 수 있다.
- 낮은 수준의 프로그래밍 구조를 가지고 있다.
C. JSP (Java Server Page)
- 동적인 웹 문서를 지원하고, 웹 문서으 ㅣ다른 처리 요구들을 위해 설계된 기술 모음이다.
- 주로, HTML과 Java의 혼합된 형태로 보인다.
- XLST와는 다른 형태의 마크업/프로그래밍 하이브리드 언어로 JSTL이 있다.
* .NET Framework 플랫폼 언어
- C#, Visual BASCI.NET, Managed C++, J#.NET, JScript.NET과 같은 언어들이 해당된다.
- 모든 .NET 언어는 CTS(Common Type System)을 사용하여 공통된 클래스 라이브러리를 제공받는다.
- CTS 명세를 수용하는 컴파일러들은 S/W 시스템으로 결합될 수 있는 객체를 생성한다.
- 모든 /NET 언어는 동일한 중간 형태인 IL(International Language)로 번역되는데, IL은 Java처럼 인터프리터로 실행되는 것이 아닌, 컴파일러(JIT 컴파일러)로 실행되어 기계 코드로 번역된다.
Software Crisis (소프트웨어의 위기)
- S/W 크기의 증가에 따른 유지, 보수의 어려움을 인한 PL 발전의 정체
- 언어적 기술보다는 조직적인 방법*으로 해결하고자 했다.
* 조직적인 방법
- 기존 코드의 재사용
- 이식성 제고
- 문법 위주의 Editor를 사용하여 생산성 제고
The Future of PL (프로그래밍 언어 설계의 미래)
- H/W와 Computer Architecture의 발달에 의해 많은 영향을 받게 될 것이다.
(Concurrent 프로그래밍, Multicore 프로그래밍, Multithread 프로그래밍 모두 하드웨어의 발전에 따른 산물들이다.)
- 새로운 PL설계보다는 기존 PL들을 개선해나가면서 PL 설계에 대한 이해를 점진적으로 증가시킬 것으로 예측된다.