프로그래밍 패러다임

프로그래밍을 업으로 삼고 있지 않은 내가 이런 글을 쓰는 게 주제넘은 일일 수도 있다. 그럼에도 현대 IT 기술에 관심이 많은 한 사람으로서 프로그래밍을 어떻게 바라보고 있는지에 대한 글을 남기는 것은 앞으로 프로그래밍을 배우고자 하는 고등학생이나, 대학생, 일반인들에게 도움이 될 것 같다는 생각에 이 글을 시작한다. 내가 이미 알고 있는 지식과, 내가 배우면서 익히는 정보들을 정리해서 남기면 누군가에게 도움이 되지 않을까?

프로그래밍 언어를 배우기 이전에, 각각의 언어가 가지고 있는 패러다임을 인지하고 있으면, 언어를 익히는 데 많은 도움이 될 것 같다. 여기서 대략적인 패러다임을 살펴보자.


절차적 프로그래밍 (Procedural Programming)

시간의 관점에서 프로그래밍하는 기법이다. 명령어를 한 줄씩 따라가며 실행되기 때문에 순차적 프로그래밍이라고도 부른다. 흔히 프로그래밍을 처음 생각할 때 가장 자연스럽게 떠오르는 방법으로, 입문 레벨에서 많이 사용된다. 반복적인 일들을 모듈화함으로써 코드를 재사용할 수 있지만, 많은 경우 코드의 수정이 필요하다. 컴퓨터의 계산이 시간의 흐름으로 이루어지기 때문에 과학계산이나, 또는 하드웨어의 제어에 주로 사용된다. 대표적으로 C, Fortran을 생각할 수 있다.

객체 지향 프로그래밍 (Object Oriented Programming)

데이터의 관점에서 프로그래밍하는 기법이다. 모든 데이터를 객체(Object)를 바라보고, 캡슐화(Encapsulation)를 통해 데이터를 불법적인(illegal) 접근으로부터 보호한다. 이로써 객체 안의 데이터(Attributes)를 항상 유효한 상태로 유지할 수 있다. 데이터를 추가, 제거, 변경하기 위해서 멤버함수(Member method)를 제공한다. 객체(Object)들 사이에 메세지를 주고받음으로 상호작용(Interaction)하도록 할 수 있다. 또한, 객체들 사이에 종속 관계를 정의함으로써 계층을 만들 수 있다. 이런 개념을 기반으로 상속(Inheritance), 다형성(Polymorphism), 추상화(Abstraction)가 정의된다. 객체들 사이의 관계를 통해 프로그램을 만들기 때문에 이를 UML diagram 형식으로 표현할 수 있다. 이벤트 중심의 프로그램(Event-driven program)이 이에 적합하다. 대표적인 언어로 C++, C#, Java, Python 등등이 있고, 최근 사람들이 가장 많이 사용하는 언어 패러다임이다.

함수형 프로그래밍 (Functional Programming)

함수의 관점에서 프로그래밍하는 기법이다. 수학의 함수에서처럼 입력과 출력을 엄밀히 정의한 후, 해당 기능을 수행하는 함수를 작성한다. 그리고 그 함수들을 잘 조합하여 프로그램을 만드는 방식이다. 언뜻 보면 다른 프로그래밍 방식과 비슷해 보이는데, 여기에서 함수(Pure Function)는 보다 엄밀한 정의를 갖는다. 즉, 함수 내부에서 다른 입력이나 출력이 있으면 안 된다. 예를 들어, 객체 지향에서의 멤버함수를 생각해보면, 입력과 출력이 정의되어 있어도, 멤버함수 내부에서 멤버변수를 변경할 수 있다. 이 멤버변수는 멤버함수의 입출력과는 별개이다. 절차적 프로그래밍에서도 호출하는 함수가 정의된 입출력과 별개의 변수를 변경할 수 있다. 순수 함수형 프로그램에서는 이런 것들이 허용되지 않는다. 오직 정의된 입출력으로만 기능을 수행한다. 대표적으로 LISP 계열의 언어나, Scala, Haskell이 이에 해당한다. 많은 현대 언어들(Java8, Python, Swift 등등)이 이러한 함수형 프로그래밍 기법을 언어에 반영하고 있다. 좀 더 자세한 내용은 함수형 프로그래밍을 참고.


이 프로그래밍의 패러다임이 모두 상호 배타적인 관계를 갖는 것은 아니다. 절차적 프로그램이면서 객체 지향일 수 있고, 함수형 프로그램이면서 절차적 프로그램일 수도 있다. 그러나 객체 지향이면서 함수형 프로그램인 것은…글쎄 나는 머릿속에 잘 떠오르지 않는다. 굳이 비유하자면 따뜻한 얼음 같은 느낌이다. 이 부분은 사람에 따라 생각이 다를 것 같다. Scala 같은 언어가 이에 해당하는 것 같은데 (객체 지향과 함수형 사이의 그 어딘가…), 내가 Scala를 직접 다루어 보지 않았기 때문에 확실히 말하지는 못하겠다.

각각의 패러다임을 대표하는 언어를 하나씩 익힌다면, 해당 패러다임을 어느 정도 이해할 수 있을 것이다. 그에 더해 새로운 언어를 배운다면, 아마도 이 3개 언어를 조합한 그 무언가일 확률이 높다. 예를 들어, 절차형 언어로써 C언어, 객체 지향 언어로써 C#, 함수형 언어로써 Haskell을 익힌다면, 그 외의 언어들 C++, Java, Python, Scala 등등을 익히는데 매우 수월할 것이다.

개인적인 생각은 하드웨어에 가장 가까운 언어로써 C언어를 배우고, 요즘 많이 쓰이는 C# 또는 Java, 그리고 함수형 언어인 Haskell을 배우면 좋을 것 같다. Haskell은 여러 가지 혼잡한 함수형 언어들을 집대성하여 만든 새로운 순순 함수형 언어이고, 인간의 생각에 가장 가까운 고수준(high-level) 언어이므로, 다른 언어보다 먼저 배우는 게 더 좋을 수도 있다.

Reply