[CS] 프로그래밍 언어의 분류

Updated:

프로그래밍 언어의 분류

수준(level)에 따른 분류

여기서 말하는 수준(level)은 언어의 좋고나쁨 의미하지는 않는다. 고수준이라는 것은 인간에게 더 친화적이라는 뜻이고 저수준이라는 것은 컴퓨터에 더 가깝게 설계된 언어라는 뜻이다.

저수준 언어

저수준 언어에는 대표적으로 기계어, 어셈블리어 등이 있다. 기계어는 1과0만을 입력하여 작성한다. 어셈블리어는 어느 정도의 명령어가 추가되었지만 그럼에도 여전히 사람보다는 기계에 가까운 언어이다. 저수준 언어는 사람 입장에서 코드를 작성하기 어렵다는 단점과 별도의 변환이 필요없다는 장점을 가지고 있다.

고수준 언어

고수준 언어에는 Java, Python 등등 요즘 사용하는 대부분의 언어가 포함된다. 기계보다는 사람에게 친화적인 언어인만큼 코드를 짜기 쉽지만 컴파일러나 인터프리터를 통해 기계가 이해할 수 있도록 기계어로 변환해주는 과정이 필수적이다.

타입(Type)에 따른 분류


<배경지식>

컴파일 Type

컴파일 타입은 전처리-컴파일-어셈블-링크의 4가지 과정을 거쳐 빌드되어 소스코드를 실행파일로 바꿔준다. 전처리는 C언어에서 #include, #define처럼 이미 정해진 것들을 먼저 처리하는 사전준비과정을 의미한다. 중요한 것은 컴파일, 어셈블, 링크인데 컴파일 과정은 우리가 작성한 프로그래밍 언어를 중간언어(고급언어와 기계어의 중간단계)로 변환하는 과정으로 보통 어셈블리어로 만들어준다. 어셈블 과정에서 어셈블러를 이용해 중간언어를 기계어로 변환하여 Object 파일을 생성한 후 마지막으로 링크 과정에서 실행파일을 만들어준다. 보통 컴파일 과정과 링크 과정을 합해 빌드라고 부른다.

이런 컴파일 언어들은 빌드가 완료된 파일의 실행속도가 빠르다는 장점이 있지만 프로그램을 수정할 때마다 매번 전체를 빌드해줘야한다는 점과 플랫폼에 의존적이라는 점이 단점으로 작용한다. 플랫폼에 의존적이라는 것은 운영체제마다 사용하는 실행파일이 다르기 때문으로 쉽게 말해서 윈도우에서 실행가능한 파일이 맥os에서는 불가능하다는 것을 떠올리면 된다.

인터프리트 Type

인터프리트 타입은 하나의 명령세트마다 인터프리터를 이용하여 바로바로 기계어로 번역해주는 방식이다. 각 운영체제에 맞는 인터프리터만 설치한다면 목적파일 생성 없이도 프로그램 실행이 가능하다. 즉, 컴파일 과정이 없기 때문에 수정과 디버깅이 용이하고 플랫폼에 독립적이라는 장점이 있다. 반면, 빌드되어 있는 컴파일 언어 프로그램보다 속도가 느리다는 단점이 존재한다.

하이브리드 Type

컴파일 Type과 인터프리트 Type을 혼합하여 각각의 장점을 모두 가지고 있는 방식으로 Java가 여기에 속한다. 크게 2가지 과정으로 나뉘는데 우선 컴파일 과정과 비슷하게 바이트코드(중간 언어)를 만든다. 그 후 VM(가상머신)을 이용하여 각 운영체제에 맞게 프로그램을 실행한다. Java언어를 예시로 들면, 첫번째 과정을 통해 .class 파일을 만든 후 JVM(Java Virtual Machine)을 이용하여 운영체제에 맞게 실행한다고 보면 된다. 사전에 바이트코드 파일을 만들어 실행속도 측면에서의 장점을 잡은 동시에 각 운영체제에 해당하는 VM만 설치한다면 플랫폼에 독립적이라는 장점까지 모두 채택한 방식이라고 할 수 있다.


프로그래밍 언어는 자료형이 어느 시점에 결정이 되는지에 따라 정적 타이핑 언어와 동적 타이핑 언어로 분류할 수 있다.

정적 타이핑 언어

자료형이 컴파일 시점에 결정되는 언어로 실행 전에 타입체크를 통해 오류를 걸러내기 때문에 실제 운용시점에서 상대적으로 오류가 발생할 확률이 적다는 장점을 지닌다. 다만, 개발자가 모든 자료형을 명시해주어야 하므로 개발 생산성 측면에서 느리다는 단점을 내포한다. 대표적으로, Java, C계열 언어들이 여기에 포함된다.

동적 타이핑 언어

자료형이 실행 시점에 정해지는 언어로 개발자가 별도로 자료형을 명시해줄 필요 없이 언어가 알아서 자료형을 유추해준다. 그만큼 개발이 편리하고 빠르다는 장점이 있지만, 실행 시점에 오류가 발생할 확률이 높다. 대표적으로, Python, JavaScript 등의 언어가 이에 속한다.

패러다임(paradigm)에 따른 분류

위에서 설명한 2가지 분류는 언어의 특성에 기준을 두었다면, 패러다임에 따른 분류는 변화하는 시대의 요구에 맞춰 분류한다. 현대사회는 빠르게 변화하고 있고 그에 따라 사회제도도 변화하는 것과 마찬가지로 언어도 시대상에 따라 요구하는 방식이 달라진다.

  1. 명령형 프로그래밍

    -> ‘무엇’을 할 것인가 보다 ‘어떻게’ 할 것인가에 집중

    절차적 언어

    컴퓨터가 수행할 명령어를 단순히 순서에 따라 나열하는 수준의 언어로 초기에 간단한 소프트웨어 개발 시에 사용한 언어이다. 순서에 따라 나열한 코드이기 때문에 가독성이 좋고 속도가 상대적으로 빠르지만 복잡한 프로그램 수정 시에 전부 수정해야하기 때문에 유지보수가 어렵다. 대표적으로 COBOLl과 BASIC이 여기에 속한다.

    객체지향 언어

    속성과 기능으로 이루어진 객체라는 개념을 도입하여 실제세계의 실체를 표현하기 더 용이한 언어이다. 추상화, 캡슐화, 상속성, 다형성 등의 특성으로 코드 재사용이 가능하고 유지보수가 용이하다. Java, C++, C# 등이 여기에 속한다.

  2. 선언형 프로그래밍

    -> ‘어떻게’ 할 것인가 보다 ‘무엇’을 할 것인가에 집중

    함수형 언어

    깨끗하고 유지보수가 쉬운 소프트웨어를 만들기 위해 코드 구성의 기본인 함수를 최상의 상태로 이용하는 것에 중점을 둔 패러다임이다. 객체지향 프로그래밍이 실제세계의 실체를 만들기 위해 큰 틀의 관점에서 설계한다면 함수형 프로그래밍은 함수라는 도구를 어떻게 더 효과적으로 사용할 수 있을지의 관점에서 바라본다. 별도의 변수 대입문이 필요없고 값이 변하지 않는다는 특성을 지닌다.


이상에서 설명한 패러다임에 따른 프로그래밍 언어의 분류는 각 시대상의 요구에 따라 탄생한 것이니만큼 과거의 언어들도 이 요구를 따르고 있다. 대표적으로 객체지향 언어인 Java 역시 함수형 프로그래밍의 특성을 포함한 람다, 스트림 등을 Java8부터 지원하기 시작하였다. 즉, 객체지향 프로그래밍과 함수형 프로그래밍은 서로 공존이 가능하다.

Tags: ,

Categories:

Updated:

Leave a comment