프래그래밍 언어랑 프로그램을 작성하기 위한 언어이며 "언어"란 무언가와 소통하기 위한 일종의 "약속"이다.
- 한국어 : 한국인과 소통하기 위한 약속.
- 영어 : 대부분의 세계인과 소통하기 위한 약속.
더 나아가 "프로그래밍 언어"란 컴퓨터와 소통하기 위한 약속(프로토콜)이다.
- 사람이 프로그래밍 언어로 프로그램을 작성
- 컴퓨터는 프로그램을 "구문구조"에 기반하여 읽고, "의미"를 이해한다.
- 컴퓨터는 이해한 "의미"를 수행하며
- 수행한 결과를 사람에게 반환한다.
Machine languages (기계어)
: 태초의 프로그래밍 언어이다. 이는 컴퓨터가 읽을 수 있는 0과 1로 구성되어 있으며 CPU마다 다른 기계어 해석 능력(ISA)을 갖는다. (x86 vs. Arm ...) 이는 사람이 읽어나 작성하긴 어렵다.
Assambly language ( 어셈블리어 )
: 저수준 프로그래밍 언어이다.
- 문자열 형태의 명령어 형태를 가지며 특정 CPU를 대상으로 하는 언어이다. 때문에 기계어와 밀접한 연관이 있으며, 일반적으로 기계어와 1:1 대응한다. ( 어셈블리 명령어 1개 -> 기계어 명령어 1개)
- 어셈블리어는 사람이 읽을 수 있는 형태이다. 때문에 기계가 바로 읽을 수 없다. 어셈블러라는 번역기를 통해 기계어로 번역해줘야만 한다. (1:1 대응이므로 쉽게 기계어로 번역)
- 높은 성능을 위해 오늘날에도 많이 사용한다. (inline assembly in c/c++)
High-level programming languages ( 고수준 언어)
: 우리가 아는 c/c++, java, python, javascript, ocaml 등을 의미한다.
- 주로 3세대 언어 이상(1세대 : 기계어, 2세대 : 어셈블리어)을 통칭한다.
- 사람이 쉽게 읽거나 작성할 수 있는 형태이다. 그래서 이 역시 기계가 바로 읽을 수 없다.
- 다른 말로 범용적인 프로그래밍 언어(general purpose)라고 부르며 넓은 범위의 문제해결에 활용한다.
- 이 언어는 하드웨어 추상화(abstraction) 특징을 가진다. 쉽게 말해 하드웨어에 대한 이해가 필요하지 않은 상태로 사용할 수 있다는 말이다.
Differences among PLs
: 언어마다 서로 다른 구문구조 및 의미를 가지며, 서로 다른 특성 및 표현력을 가진다.
분기문
- C언어 : if- else
- Ocaml : if-then-else
"and" 연산자
- python : 첫 번째 피연산자 계산 후 계산 결과가 False라면 False를 반환하고 끝냄. 만약 True라면 뒤에 있는 두 번째 피연산자 계산 결과를 반환한다.
- Ruby : 첫 번째와 두 번째 피연산자를 차례로 계산한다. 두 연산자가 모두 true라면 true를 아니면 false를 반환한다.
특성의 차이
- c언어 : 프로그램 성능에 초점을 둔다. 때문에 시스템 프로그래밍에 적합하다.
- Ocaml : 프로그램 안정성에 초점을 둔다. 때문에 애플리케이션 프로그래밍에 적합하다.
표현력의 차이
- c언어 : 포인터, 반복문, inline 어셈블리 등을 활용하여 최적화된 알고리즘을 구현한다.
- Ocaml : 함수를 값으로 활용한 간결한 프로그래밍과 불변성을 이용한 컴파일러 최적화 및 동시성 프로그래밍에 적합하다. (동시성 프로그래밍 : 2개 이상의 프로세스가 계산 중인 상태에 놓이는 것)
서로 다른 패러다임
컴퓨터에서 프로그램이 실행되는 방법
: 컴퓨터는 프로그래밍 언어를 있는 그대로 이해하지 못하기에 "번역기" 혹은 "해석기"를 활용해야 한다.
- 번역 : 언어 A를 이해할 수 있는 동일한 의미의 언어 B로 변환하는 것 (영어번역 : 영어 -> 한국어)
- 해석 : 문장 또는 행위 등의 내용을 판단하고 이해하는 것. (클래식 해설가 : 클래식 -> 감정 )
Compilation ( 번역 )
: Compilation은 프로그래밍 언어로 작성된 프로그램을 서로 다른 언어로 번역하는 행위이다.
- 주로 고수준 언어(java, c..)를 저수준 언어 (기계어)로 번역한다.
- 이 과정은 컴파일러에 의해 수행된다.
- 입력 : 프로그램 -> 반환 : 번역된 프로그램
- 입력된 프로그램에 대해 다양한 안정성 검증과정을 수행한다.
- 어휘 분석, 문법 분석, 의미 분석.. 등등
- 성능 향상 또는 프로그램 크기 축소를 위해 다양한 최적화 작업을 수행한다.
- Constant propagation, Dead-code elimination, Loop-unrolling, ...
- (이상적으로) 번역이 프로그램의 "의미"를 오역하지 않는다.
- (현실적으로) 번역의 품질에 대한 검증절차 미비.
Compiled languages는 범용적으로 활용되며 아래와 같은 소프트웨어 개발에 적합하다.
- 큰 규모의 소프트 웨어 프로젝트
- 검증과정을 통해 발생할 수 있는 오류를 사전에 탐지
- 단, 모든 종류의 오류를 탐지할 순 없음.
- 고성능 소프트웨어
- 기계로의 변환 및 최적화를 통한 성능 향상
- 시스템 소프트웨어 ( 또는 저수준 소프트웨어 )
- 하드웨어가 바로 이해할 수 있는 기계어 프로그램으로 변환.
Interpreted language에 비한 단점
- 학습 및 활용에 많은 시간과 비용 소요
- e.g. 안정성 검증을 통과하기 위해 프로그램이 갖춰야 할 조건
- e.g. 이 코드에 문제가 있나? if true then 0 else 'a'
- 컴파일 과정이 다소 비싸고 복잡
- e.g. Android framework 빌드에 1시간 이상 소요
- e.g. 컴파일 시, 여러 의존성 정의가 필요하다.
Language perspective
: 컴파일 언어는 주로 static -typed language( 정적타입 언어)이다.
- 정적 타입 언어는 컴파일 시점에 모든 변수와 표현식의 타입이 결정된다.
- 잘못된 타입 사이 연산이 발생하는 경우 컴파일 실패.
- 컴파일 시점, 타입 검사를 통해 안전한 프로그래밍이 가능하다.
몇몇 언어는 type inference(타입 추론)을 제공한다. 덕분에 개발자가 변수 및 표현식에 타입을 기재하지 않아도 괜찮다.
- 타입 시스템이 프로그램을 분석하여 자동으로 각 변수 및 표현식의 타입을 추론한다.
- 타입 시스템에 힌트를 주거나, 읽기 쉬운 코드 작성을 위해 명시적 타입 기재도 허용한다.
- Ocaml, c++(auto), 등등이 여기에 해당.
Examples
우리가 학교에서 배우고 사용해 온 대부분의 언어는 compiled languages이다.
- 프로그램이 컴파일러에 의해 기계어로 번역된다.
- c/c++ -> 이진수 (gcc, clang)
- Ocaml -> 이진수 (ocamlc)
- 프로그램이 컴파일러에 의해 가상 기계어로 번역된다.
- java -> JVML (javac)
- Scala -> JBML (scalac)
- 프로그램이 컴파일러에 의해 중간언어로 번역된다.
- c# -> MSIL (mcs)
- F# -> MSIL (fsc)
'학교 공부 > 프로그래밍 언어 개론' 카테고리의 다른 글
[프로그래밍 언어] 언어의 구조와 의미2 (0) | 2023.04.19 |
---|---|
[Ocaml] Tail Call Optimization (0) | 2023.04.19 |
[Ocaml] Lists, Type definition (0) | 2023.04.19 |
[Ocaml] Pattern matching (expression) (0) | 2023.04.11 |
[Ocaml] Module system (0) | 2023.04.09 |