프로그래밍 언어, 3번째 포스팅입니다.
슬슬 그 끝이 보이기 시작합니다..? 👀
종류 및 특징 중, 이제 패러다임과 관련된 이야기를 나눠볼까 합니다.
- 패러다임
방법 혹은 목적 (저 수준/고 수준)빌드(Build)유무 (컴파일 / 인터프리터)자료형 지정 유무
프로그래밍 패러다임과 관련된 내용은
다소 철학적이고, 단번에 이해하기 어려운 개념이므로
본 포스팅에서는 예시를 활용하여 보다 쉽게 다뤄보도록 하겠습니다.
프로그래밍 패러다임(programming paradigm)이란?
특정 관점과 접근 방식에 따른 개발자의 코딩방식
패러다임(Paradigm)의 사전적 정의는 다음과 같습니다.
한 시대의 사람들의 견해나 사고를 근본적으로 규정하고 있는 인식의 체계.
또는 사물에 대한 이론적인 틀이나 체계. 즉, 일종의 '틀'
(출처 : Oxford Languages)
프로그래밍 분야에서 이를 적용해 보자면..
개발자는 프로그래밍과 관련된 이론적 체계 혹은 틀(패러다임)에 따라
'어떻게 프로그래밍을 할 것인가' 란 의문을 스스로 던지고,
특정 관점과 방식을 바탕으로 '프로그래밍'을 실시하게 되는 셈입니다.
상당히 철학적인 이야기가 아닐 수 없네요.
프로그래밍 패러다임의 변화
- 통상, '프로그래밍 패러다임'이라 하면 아래 3가지를 의미합니다.
- 절차적 프로그래밍 (PP, Procedure Programming)
- 객체지향 프로그래밍 (OOP, Object Oriented Programming)
- 함수형 프로그래밍 (FP, Functional Programming)
- 해당 분류는 각 패러다임이 프로그래밍 분야에서 각광받은 시점과도 동일합니다.
- 다만, 등장 순서는 이와 정 반대로 함수형 ➟ 객체지향 ➟ 절차적 입니다.
- 그러므로, 프로그래밍 패러다임은 단순히 진화론적 관점에서 우열을 판단할 수 없습니다.
- 프로그래밍 패러다임은 '접근 방식'과 '사용 환경'에 따라 유동적으로 활용됩니다.
- 각각의 프로그래밍 패러다임은 장단점이 존재하며, 이에 상호 보완적 특성을 가집니다.
프로그래밍 패러다임의 분류
- 앞서, 3가지 주요 프로그래밍 패러다임은 [방법/목적]에 따라 재 분류됩니다.
- 명령형 프로그래밍(Imperative Programming)
- 절차형, 객체지향적 프로그래밍
- 선언형 프로그래밍(Declearative Programming)
- 함수형, 논리형 프로그래밍
- 명령형 프로그래밍(Imperative Programming)
명령형 프로그래밍 vs 선언형 프로그래밍
어떻게(How) 할것인가, 무엇(What)을 할 것인가?
프로그래밍 메인 스트림 패러다임인 선언형 / 명령형 프로그래밍에 대하여
각각의 정의와 차이를 살펴보기 위해 2가지 예시를 들어보도록 하겠습니다.
예시1. 가공된 큐브 치즈를 생산하는 공장
- 당신은 치즈를 생산하는 공장의 관리자입니다.
- 오는 7월의 치즈 생산을 위해 직원들에게 다음과 같이 지시합니다.
명령형 접근(HOW)을 통해 치즈를 생산할 경우,
공통의 목표와 주의사항을 설정 ➟ 세부 공정과정(우유살균, 응고 및 숙성 등)을 관리 ➟ 생산을 완료합니다.
선언형 접근(WHAT)을 통해 치즈를 생산할 경우,
목표(기간, 수량)만을 던져주고 ➟ 생산을 지시 ➟ 생산을 완료합니다.
- [명령형 접근]은 치즈를 생산하는 과정(HOW)에 대해 포커스를 집중합니다.
- 따라서, 해당 과정마다 구체적인 임무를 제시하고 일부 참고사항까지 제시합니다.
- 이와 반대로, [선언형 접근]은 단순히 치즈의 생산(WHAT)만이 유일한 관심사입니다.
- 임무의 세부 지시사항과 절차를 미리 레시피로 학습 한 상태라고 추상화, 즉 가정한 상태입니다.
- 결과적으로, 공장관리자는 '지시'만 내리는 행위만으로도 결과물(OUTPUT)을 도출합니다.
- 즉, [선언형 접근]을 위해 명령형 단계가 이미 추상화되어 있다는 가정이 뒷받침 되어야 한다는 점입니다.
예시2. 배열 내 각각의 값을 제곱하는 함수 만들기
- 명령형 프로그래밍을 통한 예시 코드는 다음과 같습니다.
- multiply란 명칭의 함수가 동작하고, 값을 반환하기 위해 총 3개의 단계를 거칩니다.
- 빈 배열을 생성하고 ➟ 조건문을 사용해 제곱기능을 만들고 ➟ 요소가 담긴 배열 반환
func multiply(number: [Int]) -> [Int] {
var someNum: [Int] = [] // 1. someNum이란 빈 배열을 만들어 주고
for i in 0..<number.count {
someNum.append(number[i] * number[i])
}
// 2. for 조건문을 통해 각각의 배열의 요소가 해당 값의 제곱값으로 변환되어 포함될 수 있도록 하고
return someNum // 3. 그 결과를 요소로 담아 새로운 배열을 반환한다.
}
multiply(number: [1,2,3]) // [1,4,9]
- 반면에, 선언형 프로그래밍을 통한 동일한 기능의 코드는 다음과 같습니다.
- 상당히 단순하게 바뀌었습니다!
- 'map' 고차함수는 Swift Framework 에 이미 내장되어 있는 기능입니다.
- map 또한 이미 명령형 프로그래밍 방식으로서 코드의 기능이 작성되어 있습니다.
(단지, map이란 명칭으로서 추상화, 전제되어 있는 것입니다)
func multiply2(number: [Int]) -> [Int] {
return number.map {$0 * $0 } // map 고차함수를 활용
}
multiply2(number: [1,2,3])
프로그래밍 패러다임 첫 번째 포스팅이 마무리 되었습니다.
다음 포스팅에서는 아직 자세히 다루지 못한
절차적 / 객체지향적 / 함수형 프로그래밍 에 대해
하나씩, 차근차근 살펴보도록 하겠습니다.
'CS > Computer Basic' 카테고리의 다른 글
[CS/Basic] 절차적 프로그래밍은 '절차지향'이 아니다! (0) | 2023.01.05 |
---|---|
[CS/Basic] 그래서, 객체(Object)가 무엇인가요? (0) | 2022.12.29 |
[CS/Basic] 컴파일 에러와 런타임 에러는 언제 발생하나? (0) | 2022.12.06 |
[CS/Basic] 컴파일? 인터프린터? 빌드(Build) 유무에 따른 비교 (0) | 2022.12.05 |
[CS/Basic] 컴퓨터와 개발자가 소통하는 방법, 프로그래밍 언어 (0) | 2022.12.04 |
댓글