| 프로그래밍 패러다임 |
| --- |
| * 행위
* 에이전트 지향
* 배열 지향
* 오토마타 기반
* 병행 컴퓨팅
	+ 상대주의적 프로그래밍
* 데이터 기반
* 선언형 (반의어: 명령형)
	+ 함수형
		- 함수 논리형
		- 순수 함수형
	+ 논리형
		- 가추법
		- Answer set
		- 병행 논리
		- 함수 논리
		- 귀납적 논리
	+ 제약
		- 제약 논리
			* 병행 제약 논리
	+ 데이터플로
		- 플로 기반
		- 반응형
* 동적/스크립트
* 사건 기반
* 함수 레벨 (반의어: 값 레벨)
	+ 포인트 프리 스타일
		- 연결식
* 제네릭
* 명령형 (반의어: 선언형)
	+ 절차적
	+ 객체 지향
* 문학적
* 언어 지향
	+ 자연어 프로그래밍
	+ 규율 지향
	+ 도메인 특화
	+ 문법 지향
	+ 의도적
* 메타프로그래밍
	+ 자동
		- 귀납적 프로그래밍
	+ 반영
		- 속성 지향
	+ 매크로
	+ 템플릿
* 비구조적 (반의어: 구조적)
	+ 배열
* 비결정
* 병렬 컴퓨팅
	+ 프로세스 지향
* 확률론적
* 스택 지향
* 구조적 (반의어: 비구조적)
	+ 블록 구조
	+ 객체 지향
		- 행위자 기반
		- 클래스 기반
		- 병행
		- 프로토타입 기반
		- 관심사의 분리에 따라:
			* 관점 지향
			* 역할 지향
			* 주체 지향
	+ 재귀
* 심볼릭
* 값 레벨 (반의어: 함수 레벨)
* 퀀텀 프로그래밍
 |
| * v
* t
* e
 |

**프로그래밍 패러다임**(programming paradigm)은 프로그래밍의 패러다임 형태이다. 소프트웨어 공학을 할 때의 패러다임 형태인 방법론과 비교된다.

프로그래밍 패러다임은 프로그래머에게 프로그래밍의 관점을 갖게 해 주고, 결정하는 역할을 한다. 예를 들어 객체지향 프로그래밍은 프로그래머들이 프로그램을 상호작용하는 객체들의 집합으로 볼 수 있게 하는 반면에, 함수형 프로그래밍은 상태값을 지니지 않는 함수값들의 연속으로 생각할 수 있게 해준다.

소프트웨어 공학의 서로 다른 무리가 서로 다른 *방법론*을 지원하듯이, 서로 다른 프로그래밍 언어는 서로 다른 *프로그래밍 패러다임*을 지원한다. 어떤 언어들은 하나의 특정한 패러다임을 지원하기도 하는데, 스몰토크와 jdk 1.8 이전의 자바가 객체지향 프로그래밍을 지원하는 반면에, 하스켈과 스킴은 함수형 프로그래밍을 지원한다. 여러 가지 패러다임을 지원하는 언어들도 있는데, 커먼 리스프, 파이썬, 오즈, jdk 1.8 이상의 자바 등이 이런 언어들이다. (*몇년 전까지 자바는 명령형 프로그래밍, 객체지향 프로그래밍 패러다임을 따르기로 유명했다. 하지만 jdk 1.8부터 함수형 프로그래밍 패러다임을 지원하기 위해 람다식, 생성자 레퍼런스, 메서드 레퍼런스를 도입했고 선언형 프로그래밍의 장려를 위해 Stream과 같은 표준 API 등도 추가했다. 그러나 태생부터 함수형 패러다임을 지원하는 여타 언어들과는 달리 여전히 함수를 일급객체로 취급하지는 않는다. 자바에서 람다식은 함수형 인터페이스를 구현하는 익명클래스의 인스턴스를 생성하며, 좀 더 간단한 표현을 위해 컴파일러의 타입 추론이 동원된다.* )

많은 프로그래밍 패러다임은 어떤 기법을 금지하거나 어떤 것을 가능하게 하는 것으로 널리 알려져 있다. 예를 들어, 순수 함수형 프로그래밍은 부작용의 사용을 허용하지 않는다. 구조적 프로그래밍은 GOTO문의 사용을 제한한다. 부분적으로 이런 이유로 인하여 새로운 패러다임들은 종종 과거의 것에 길들여진 사람들에게 교조주의적이거나 지나치게 엄격한 것으로 간주되기도 한다. 하지만 특정 기법을 피하는 것은 프로그래밍 언어의 범용성을 제한하지 않으면서 프로그램의 올바름에 대한 정리를 증명하는 것을 더 쉽게 하고, 더 간단하게 이해할 수 있기도 하다.

프로그래밍 패러다임과 프로그래밍 언어와의 관계는 프로그래밍 언어가 여러 프로그래밍 패러다임을 지원하기도 하기 때문에 복잡할 수도 있다. 예를 들어서 C++는 절차적 프로그래밍, 객체기반 프로그래밍, 객체지향 프로그래밍, 제네릭 프로그래밍의 요소들을 지원하도록 설계되었다. C++에서는 순수하게 절차적 프로그램을 작성할 수 있고, 순수하게 객체지향 프로그램을 작성할 수 있으며, 두 가지 패러다임 모두의 요소를 포함한 프로그램을 작성할 수도 있다. 최근에는 여러 패러다임들이 관대하게 지원되는 경향이 강하다. 자바나 PHP와 같이 기존부터 있던 언어들에는 본래 없던 패러다임이 추가되고, Swift나 Go, Kotlin과 같이 비교적 새로 만들어지는 언어들은 처음부터 여러 패러다임의 지원을 고려하여 설계된다. 범용성을 강조하는 언어들에서는 최근 함수형, 선언형 패러다임이 적극적으로 적용되고 있는 것이 특징이다. DSL과 같이 완전히 특수한 목적을 띄지도 않고, 완전한 범용성을 띄지도 않는, 어느 정도의 범용성을 띄는 새로운 언어들이나, 또는 실험적으로 개발되는 많은 언어들에서는 어느 정도 언어 설계의 목적에 따라 여러 패러다임을 조합하는 일이 더욱 흔해지고 있다. 고전적으로 순수한 관점에서 이질적으로 보여졌던 패러다임간의 공존이 갈수록 많이 등장하며, 상황과 맥락에 따라 패러다임간 장점만을 취하려는 시도는 계속되고 있다.

위와 같이 하나의 언어가 여러 패러다임을 지원하는 시도가 늘어가고 있음에도, 반대로 개발자가 서로 다른 패러다임에 강점이 있거나 서로 다른 플랫폼에 기반한 여러 언어를 배워 사용하는 경우가 늘어가고 있다. 한 개발자가 여러 언어와 여러 패러다임을 익히는 것을 Polyglotism이라 하고, 하나의 프로젝트에서 여러 언어의 여러 패러다임을 사용하는 것을 폴리글랏(polyglot) 프로그래밍이라고 한다. 기존과 달리, 하나의 프로젝트를 수행하는 데 고려해야 하는 환경이 다양해지고, 또는 특정 작업에 최적화된 여러 툴, 프레임워크, 언어가 등장하고, 문제의 복잡도와 규모가 커지면서 폴리글랏이 트렌드로 자리잡고 있다. 예를 들어, 안드로이드 앱 개발자는 기본적으로 자바와 안드로이드를 알지만, 때로 웹 앱 개발이 유리한 경우에는 HTML, CSS, Javascript의 사용이 필요할 수 있고, 안드로이드 공식 개발 언어가 Kotlin으로 바뀌었으므로 그 또한 필요할 수 있다. 해당 안드로이드 앱 개발자는 패러다임 측면에서 명령형, 객체지향 패러다임을 넘어 선언형, 함수형 패러다임을 아는 것이 필요할 것이고, 최근 각광받는 반응형 프로그래밍도 필요할 수 있으며, 하이브리드인 함수형 반응형 프로그래밍을 사용할 수 있다. 또한, 앱은 서버와 통신하는 경우가 많은데, 스타트업이나 1인 개발과 같이 개발자가 적은 경우, 서버개발에 필요한 언어도 요구될 수 있다. 다른 예로는 자바 기반 프로젝트의 특정 맥락에서 자바 대신 자바 가상머신 지원 언어를 사용하는 것을 생각해 볼 수 있다. 또는 파이썬이 타 언어와 호환이 용이함을 이용해 Python 기반 개발 환경에서 특정 맥락서 C를 사용하는 것은 익히 알려진 패턴이다. 데이터베이스 사용에선 RDBMS를 주로 사용하던 이전과 달리 NoSQL의 대두로 여러 패러다임의 이해가 요구될 수 있다. ( *NoSQL 은 RDB의 관계지향 패러다임과 같이 하나의 패러다임이 적용된 것이 아니고, 여러 다양한 철학이 적용되어 있다. 크게 분류하면 column, document, key and value, graph의 4종류가 있다.* ) 이전부터 이러한 요구는 잠재적으로 있어왔지만, 특히 최근 서로 다른 환경, 플랫폼, 언어가 서로 호환되도록 개발되었기 때문에 과거에는 가능하지 않았던 폴리글랏 프로그래밍이 가능하게 된 측면도 있다.

여러 프로그래밍 패러다임
-------------

* 구조적 프로그래밍과 비구조적 프로그래밍
* 명령형 프로그래밍과 선언형 프로그래밍
* 메시지 전달 프로그래밍과 명령형 프로그래밍
* 절차적 프로그래밍과 함수형 프로그래밍
* 값수준 프로그래밍과 함수수준 프로그래밍
* 흐름처리 프로그래밍과 이벤트처리 프로그래밍
* 스칼라 프로그래밍과 배열 프로그래밍
* 객체지향 프로그래밍중 클래스기반 프로그래밍과 프로토타입기반 프로그래밍
* 제한형 프로그래밍과 논리형 프로그래밍
* OLE에서의 컴포넌트지향 프로그래밍
* 애스펙트제이의 애스펙트지향 프로그래밍 (Aspect Oriented Programming에서 Aspect는 '관심사', '관점'으로 해석되고, 우리 말로 관점지향 프로그래밍, 약어로 AOP 라고 한다. AspectJ는 자바 개발자들에게 유명하지만, AOP는 여러 언어에서 언어 자체적으로, 또는 프레임워크들을 통해서 구현되는 독립적인 패러다임이다.)
* 매스매티카의 규칙기반 프로그래밍
* 마이크로소프트 폭스프로의 테이블지향 프로그래밍
* 유닉스 명령줄의 파이프라인 프로그래밍
* 객체기반 프로그래밍
* 탈객체 프로그래밍
* 주체지향 프로그래밍
* 반사적 프로그래밍
* 스프레드시트의 자료흐름 프로그래밍
* 정책기반 프로그래밍
* 어노테이티브 프로그래밍 -  (영문자료)
* 특성지향 프로그래밍 (어노테이티브 프로그래밍과 같은 것일지도 모른다) (XDoclet 클래스에 의해 전처리되는 자바 5의 annotation; C#에서의 특성(Attributes))
* 개념지향 프로그래밍 (메인 프로그램 생성에 개념을 사용하는 것에 기반되어 있다)
* 반응형 프로그래밍