본문 바로가기
카테고리 없음

프로그래밍 언어의 분류

by winter-lover 2022. 3. 15.

다양한 프로그래밍 언어로 어떤 것을 선택해야 하는지 막막할 때가 있습니다. 해당 언어가 가진 특징들을 파악하고 목적에 맞는 언어를 선택해야 하는데, 프래그래밍 언어의 분류 방법에는 처리방식과 패러다임에 의한 분류가 있다. 

 

 

처리방식에 의한 분류 | 인터프리터와 컴파일러

 

일반적으로 처리계는 크게 3가지로 나눌 수 있다. 

 

1. 소스코드에서 문법을 해석하는 부분

2. 라이브러리

3. 소프트웨어 동작/실행

 

1의 경우, 프로그램의 실행 전 아무것도 아무것도 하지 않는 처리방식을 가진 것을 '인터프리터'라고 한다.

실행 전에는 변환과정이 거의 없기 때문에 사람이 작성한 소스코드를 한 줄씩 해석하면서 실행하는 식이다.

반면, 해석파트에서 실행 환경에 맞춘 코드를 생성하는 것을 '컴파일러'라고 한다.

컴파일러의 경우는 사람이 작성한 소스코드를 변환해서 컴퓨터가 실행하기 쉽게 한다.

 

예를 들면 C언어에서 컴파일러가 '목적(Object)코드'를 생성해 '링커(linker)'가 라이브러리를 호출하고 실행 형식의 파일을 '로더(loader)'가 실행한다.

또 Java처럼 컴파일러가 변환을 하지만, 가상 머신을 위해서 생성한 코드(바이트코드)를 사용해서 하드웨어에 의존하지 않는 코드를 생성하는 경우도 있다. 이 경우 생성된 바이트코드를 실행 환경인 '런타임'의 관장한다. 

 

그러나 최신 언어 중에는 목적 코드를 생성하지 않고 실행 전에 소스코드를 일단 내부 표현으로 변환해서 실행하는 방식을 채택한 언어도 있다. 인터프리어에서는 처리를 순차적으로 하기 때문에 속도가 느리지만, 내부 표현을 사용하는 것으로 처리가 빨리지기 때문이다.

런타임 안에서 바이트코드에서 기계어로 변환하는 JIT(Just In Time) 컴파일러 등의 프로그램으로 단순하게 인터프리터 혹은 컴파일러로 분류하는 것이 애매해졌다. 

거기에 어떤 언어 소스코드에서부터 다른 언어의 소스코드를 생성하는 '트랜스파일러'라는 개념도 등장했다. 

 

패러다임에 의한 분류 | 절차형, 객체지향형, 함수형

유저가 어떤 시점에서 프로그램을 구현할지를 생각하는 것이 '프로그래밍 패러다임'이라고 할 수 있다. 크게 명령형과 선언형으로 나눌 수 있다. 

 

명령형은 어떻게 처리 할까에 포커스를 두고 있다. 즉, 컴퓨터가 처리하는 순서를 프로그래밍한다. 한편 선언형은 그 처리가 무엇인지에 대해 포커스를 두고 있다. 컴퓨터에 어떤 것에 대한 정의를 내리면 그것에 따라 동작한다.

 

절차형

예를 들어 보자. 쇼핑 사이트에서 장바구니에 담겨 있는 상품의 금액을 계산하는 시나리오를 가정해보면 절차형의 경우,

 

1. 합계금액을 0원으로 한다.

2. 상품이 장바구니에 남아 있는 동안에 3,4를 반복한다. 장바구니가 비면 5를 진행한다.

3. 상품을 장바구니에서 하나 꺼낸다.

4. 꺼낸 상품의 가격을 합계금액에 더한다.

5. 합계금액의 값을 반환한다. 

 

그러나 함수형에서는 아래와 같이 구현될 것이다.

 

1. 합계금액은 장바구니 안의 상품을 아래의 규칙으로 처리한 결과의 값이다.

2. 상품이 0개일 경우 함계금액은 0이다.

3. 상품이 1개 이상일 경우 함계금액은 장바구니 안의 상품 1개의 가격과 나머지 상품의 함계금액을 더한 값이다.

 

어느 쪽이든 결과는 같지만 처리과정이 다르다. 어떤 한 쪽이 좋고 나쁘다라기 보다는 방식의 차이이기 때문에 여러가지 언어의 처리방식을 알고 있으면 다양한 일의 처리방식을 배울 수 있다.

 

객체지향형

객체체지향형은 처리 대상을 추상화 한 개념으로 처리 대상의 데이터와 그 데이터에 대한 조직을 한 묶음으로 처리한다. 예를 들면, 쇼핑몰 사이트의 장바구니라면 안에 들어 있는 데이터와 그 데이터에 대한 조작이 하나로 묶여 있어서 편리하게 관리할 수 있다. 장바구니에 추가할 상품도 같은 방식으로 데이터 조작을 하나로 묶어서 추가와 삭제 등의 조작을 통해서 처리를 하도록 되어있다. 이 때 데이터에 직접 접속하지 않고 조작을 통해서 데이터를 변경하는 것이 핵심이다. 따라서 데이터의 형식을 변경하는 등의 수정이 발생해도 조작이 변하지 않으면 영향범위가 좁아진다. 직접 데이터를 변경할 수 없기 때문에 잘못된 값이 저장되는 것을 막을 수 있고, 마음대로 값을 변경할 가능성도 없어진다. 결과적으로 프로그램의 가독성이 높아져서 개발 효율이나 생산성이 높아지게 된다고 볼 수 있다. 

 

이런 객체 지향형이라는 단어는 설계나 모델링, 개발 등 다양한 상황에서 사용된다. 

 

함수형

무엇을 함수형이라고 부를지는 여러 가지 의견이 있고 '람다 대수'라고 불리는 함수 개념을 근원으로 하는 것이 일반적이나, 이름 그대로 '함수'를 조합해서 구현한다고 이해하는 것이 간단할 것이다. 다만 절차형이나 객체지향에 있어서도 '함수'나 '메소드'라는 단어는 등장한다. 

함수형의 특징으로 1급함수가 있다. 1급함수를 사용하면 함수의 인자로서 함수를 전달하는 것이 가능해서 실행 시 동작을 생성할 수 있다. C언어에서는 함수의 인자로서 함수를 전달할 수 있지만, 실행 시에는 생성할 수 없다. 

 

절차형 프로그래밍에서는 함수에 값을 대입해서 값을 변환하면서 처리를 실행하지만 함수형 프로그래밍에서는 상태를 가지지 않고 함수 호출에 의해서 처리를 실행하는 것이 일반적이다. 즉 함수형 언어에서는 한 번의 변수 값을 설정하면 이후에 다른 값으로 변경할 수 없다. 그래서 값을 함수에 잘 전달해 그 처리 결과를 얻는 것으로 처리를 한다.

함수형 언어에서 프로그램은 복수의 형식을 처리하기 위해서 함수를 적용해 가는 방법이라고 할 수 있다. 결과적으로 반복과 같은 처리를 실행하기 위해서 임시 변수를 사용하지 않고 '함수의 재귀호출'로 구현하는 것이 일반적이다. 


 

멀티패러다임의 등장

앞에서는 패러다임에 의한 프로그래밍 언어의 분류를 소개했지만 각각의 언어가 대응하고 있는 패러다임이 하나라고 인한정할 수는 없다. 하나의 언어가 복수의 패러다임에 대응하고 있는 언어도 많이 등장하고 있어 멀티패러다임이라는 개념이 생겼다.

예를 들면 Python은 객체지향 언어이기도 하고 동시에 함수형 언어이기도 하다. 멀티 패러다임의 프로그래밍 언어가 등장하자 프로그래밍 패러다임과 프로그래밍 언어와의 관계성이 복잡해졌다. 같은 언어로 써도 사고방식을 바꾸면 전혀 다른 방식으로 쓸 수 있다. 즉, 설계 시에 어떤 패러다임을 선택하는지에 따라서 구현이 크게 달라지게 되는 것이다. 

 

물론 프로그램 중 일부의 처리를 함수형으로 만들고 다른 부분을 객체지향형으로 만드는 것도 가능하다. 다만 프로그래밍 패러다임에는 일반적으로 '바람직하지 않은 구현'이 존재한다. 예를 들면, 순수 함수형 언어에서는 부작용이 인정되고 있지 않다. 즉, 함수를 몇 번 호출하든 결과가 바뀌는 방식의 구현은 할 수 없다.

 

또 구조화 프로그래밍은 지정한 처리로 점프하는 것 같은 goto 문은 사용하지 않는 것이 전제이다. 물론 사용할 수도 있지만 유지보수성 등을 생각했을 때 피해야 하는 것으로 여겨지고 있다. 이것은 고급 언어에서는 루프를 제어할 수 있기 때문에 goto 문을 사용할 필요가 없기 때문이다.

 

어셈블리어와 같은 언어에서는 점프를 기술하기 위해서 goto 에 해당하는 문을 사용하지만 goto 문을 사용하면 분기인지 루프 안인지를 판단할 수 없기 때문에 프로그램의 동작을 눈으로 쫓는 작업이 필요하게 된다. 

 

어떤 패러다임을 선택하는지에 따라서 그 프로그램의 특징이 결정되만, 이미 존재하는 프로그램을 수정하는 경우에는 기존 프로그램에서 사용되고 있는 패러다임을 따라 개발하면 관리가 편리하다. 

 

이식성에 대한 사고 방식

하나의 소스코드로 다른 환경에서 실행할 수 있는지를 고민하는 사람이 많은 것이다. 프로그래밍 언어를 선택할 때 이런 이식성에 대한 사고방식도 시대와 함께 변화하고 있다. 

예를 들면 어셈블리어의 경우, 다른 환경에 이식하는 것은 매우 어려웠다. 하지만 C언어와 같은 언어에서는 언어 사양이 표준화 되어 있어서 다른 환경에서도 컴파일이 가능하게 되었다. 더욱이 Java나 Flash 같이 바이트코드를 생성하면 어디서나 실행할 수 있는 것도 등장했따. JavaScript처럼 브라우저 상에서 실행되는 것이면 브라우저만 있으면 어디서든 실행할 수 있다. 

JavaScript에 의한 Electron이나 C#을 사용한 Xamarin과 같은 소스코드로 데스크톱 앱이나 IOS, Android 등 복수의 환경에서 동작하는 것을 개발하는 경우도 늘고 있다.