1. 프로그래밍 패러다임
- 프로그램을 작성하는 전형적인 방식.
- 특정 언어에 종속적인 것이 아닌, 프로그래머가 추구하는 프로그램 작성 방식.
2. 프로그래밍 패러다임의 변화 : 함수형 --> 논리 --> 객체지향
- 데이터가 저장된 메모리를 관리하는 것이 어려운 문제로 대두
--> 함수형 프로그래밍 패러다임 등장
- 계산 절차를 문제의 조건으로 명시하는 규칙으로 생각
--> 논리 프로그래밍 패러다임 등장 : 선언적 프로그래밍 패러다임의 한 종류
- 같은 데이터에 대해, 다른 처리 절차를 여러 개 명시해야 하는 경우가 흔히 발생
--> 객체지향 프로그래밍 패러다임 등장
3. 프로그래밍 패러다임 변화의 배경
1) 응용 도메인의 변화
- 요구사항의 변화
- 계산분야 --> 다양한 응용 분야
2) 프로그램 구성 방식의 변화
- 명령어 나열 --> 존재하는 모듈의 조합
3) 계산 모델의 변화
- 튜링기계 모델 --> 새로운 방식의 계산 모델
4. 프로그래밍 패러다임 vs 프로그래밍 언어 패러다임
- 프로그래밍 패러다임 : 프로그램을 작성하는 방식이나 스타일
- 프로그래밍 언어 패러다임 : 해당 프로그래밍 언어가 지원하는 프로그래밍 패러다임
ㄴ 일반적으로 하나의 프로그래밍 언어는 여러 프로그래밍 패러다임을 지원함.
5. 주요 언어의 프로그래밍 패러다임
6. 프로그래밍 패러다임의 양립성
- 다양한 프로그래밍 패러다임은 서로 양립 가능함.
- 새로운 패러다임의 등장으로, 이전에 있던 패러다임이 더욱 공고히 완성됨.
- 주류 프로그래밍 패러다임이 바뀜에 따라서 이를 언어가 수용하는 방식으로 변화됨.
ex) Python : 명령형 패러다임, 절차형 패러다임 지원
---> 함수형 패러다임, 객체지향 패러다임을 포함.
7. 여러 패러다임 프로그램의 예시
1) 명령형 프로그래밍
- 프로그램 : 일련의 명령어를 나열한 것. ===> 프로그램 = 명령어의 나열
ㄴ 단순히 명령어를 쭉 나열해서 코딩.... --> 이해하기 쉬움.
- 장점 : 프로그램을 쉽게 이해할 수 있음.
- 단점 : 프로그램이 복잡한 경우, 효과적으로 다룰 수 없음.
ex) BASIC
HOME
INPUT "Enter A: ";A : INPUT "Enter B:";B
IF A < B THEN C = A : A = B : B = C
REM C = A MOD B (A modulo B)
LET C = A - INT(A/B)*B
LET A = B : B = C
IF B > 0 GOTO 40 // 40줄로 감 (4번째 줄)
// 명령형에서는 GOTO를 사용해서 여기저기 점프해서 사용 가능 :)
// 하지만 기본적으로는 한 문장 한 문장, 순서대로 처리됨
PRINT "GCD is ";A
END
실행결과)
Enter A : 126
Enter B : 312
GCD is 6
※ GCD (최대공약수) 구하는 법 : 유클리드 호제법
--> 이 예시들에서는 '유클리드 알고리즘'을 각각의 언어로 표현하였음.
참고) 유클리드 호제법
2) 절차형 프로그래밍
- 프로그램 : '서브루틴'이라는 절차의 집합 ===> 프로그램 = 절차들의 모임.
ㄴ 앞서봤던 명령형 프로그래밍처럼 매번 명령어들을 하나하나 작성하는 것이 아니라,
미리 만들어진 절차가 있으면 그것들을 잘 가져다 써서 프로그래밍 가능.
ㄴ 서브루틴을 잘 활용하면 재귀호출이 가능. --> 간단하게 프로시저를 만들 수 있다.
- 장점 : 재귀호출을 사용하여 프로시저를 간단하게 정의
ex) Algol
// PROC : 프로시저. ===> 즉, gcd라는 프로시저(절차)를 하나 만들어냄.
PROC gcd = (INT a, b) INT: (
IF b = 0 THEN
a
ELSE
gcd(b, a MOD b) // 재귀호출
FI
);
main:(
INT a = 126, b = 312;
printf(($x"The gcd of"g" and "g" is "gl$,a,b,gcd(a,b)))
)
// 이전에 만들어놓은 gcd라는 절차(프로시저)를 사용해서 간단하게 코딩 가능! :)
실행결과)
The gcd of +126 and +312 is +6
3) 구조화 프로그래밍
- goto 없이 프로그램을 작성하는 방법
ㄴ 구조화 프로그래밍이 발생하게 된 계기는, 사실 'goto 없이 만들어보자.'고 해서 발명되었음...
goto 계속 쓰다보니까 헷갈려서. ㅎㅎ 꼬이게 되는 경우가 발생하기 때문에... 그걸 막아보기 위해서..
==> structure를 만들어서 언제나 A부터 Z까지, '나는 이 틀안에서만 움직일거야.' 이런 식으로 동작.... 하게끔...
ㄴ (1강) 구조화 : 어떤 틀을 잘 만들 수 있어서 그 한 덩어리들을 잘 모으고,
그것들을 통해서 전체적으로 구조화된, 잘 정의된 프로그램을 만드는 것.
- 블록과 서브루틴을 이용
- 구조화된 제어문을 사용
ㄴ 앞서봤던 BASIC에서는 IF문을 보고 필요하면 GOTO해서 어디로 가 버렸음.
구조화 프로그래밍에서는 이게 아니라, 구조화된 제어문이란 '중첩된 구조문'이라고 표현하는데,
예를 들어 IF문이 있으면 이 조건이 맞으면 IF 중괄호가 시작하는데부터 끝나는데까지, 이 조건문 자체를 중첩시켜서
IF문 안에 다른 문장을 넣을 수 있는 것. 즉, IF 안을 수행하도록 하는 것... ==> 구조화 프로그래밍.
ex) C
#include <stdio.h>
int main() {
int a, b, c;
printf("Enter a and b: ");
scanf("%d %d", &a, &b);
do {
c = a % b;
a = b;
b = c;
} while (b > 0);
printf("gcd: %d\n", a);
return 0;
}
실행결과)
Enter a and b : 126 312
gcd : 6
4) 객체지향 프로그래밍
- 프로그램 : 서로 통신할 수 있는 객체(object)의 집합. ===> 프로그램 = 객체의 집합.
- GUI 개발에 큰 획(Smalltalk)
- 프로그램 재사용 편의로 S/W 생산성에 크게 기여
- 객체의 개념
ㄴ 객체 : 상태를 유지하며 외부의 요청에 반응하는 데이터
ㄴ 하나의 객체 안에는, 1) 상태: 필드(멤버변수) 와 2) 반응 : 메소드(멤버 함수) 가 필요함.
==> 이 둘이 묶여서 하나의 객체가 됨.
ㄴ 상태는 외부에 숨기고, 메소드는 외부에 공개!
ex) Smalltalk
// igcd 객체 정의
igcd := [ :a :b |
|u v|
u :=a. v:=b.
[ v > 0 ]
whileTrue: [ |t|
t := u.
u := v.
v := t rem: v
].
u abs // u값은 외부에 노출되지 않고 객체 내부에 잘 가지고 있음.
].
(igcd value: 126 value: 312) printN1.
// igcd 객체를 사용할 것인데, 첫번째 값은 126, 두번째 값은 312를 주겠다.
// (igcd ~~~ ) : 이게 객체임.
// u값은 외부에 노출되지 않고 객체 내부에 잘 가지고 있음
// ===> (igcd ~~~ ) 이 객체를 printN1을 통해서 마지막 값을 출력해줄 수 있음.
실행결과)
6
5) 함수형 프로그래밍
- 데이터는 값으로, 명령어는 함수로 취급. ==> 명령어가 데이터를 바꿀 수 없음
ㄴ 세부설명)
데이터를 어떤 장소에 두는 데 개의치 않고, 그냥 오직 값으로만 봄.
함수에 값을 던져주면 함수가 뭔가 작업을 한 다음에 결과값을 돌려줌.
==> 데이터는 항상 값으로 처리하게 되고, 그 값을 처리하는 명령어들은 다 함수로 취급함.
즉, 함수는 결과값만 얻을 수 있는 것이지 그 함수에 들어간 인자를 건드릴 수는 없다.
==> 함수형 프로그래밍에는 대입연산자가 없음. ==> 반복문도 불가. (카운트 자체가 불가...)
대입과 반복문이 없고 대신에 재귀호출로 처리함.
- 대입문과 반복문 없음
- 함수 자체도 값으로 취급 가능.
ㄴ 자기 자신, 즉 함수 자체도 값으로 취급함.
ex) Haskell - 함수와 인자가 괄호 없이 연속해서 나열된다. ex) igcd a 0 = abs a
module Main (main) where // Haskell에서는 module 단위로 코딩함.
main :: IO () // IO 라는 결과값을 되돌려줌
main = putStrLn (show (igcd 126 312)) // main은 이 일을 한다
// igcd를 정의
// 괄호가 없음. 함수형 프로그래밍에서는 함수 이름과 인자가 일렬로 나열됨.
igcd a 0 = abs a // 입력값이 0이 되면 그것을 최대공약수로 보내면 된다.
igcd a b = igcd (abs b) (a 'mod' (abs b)) // 0이 아닌 두 값이 들어오면, 두번째 값하고 첫번째 값을 두번째로 나눈 나머지 값을 인자로 해서 또 igcd한다...
6) 선언적 프로그래밍과 논리 언어
- 프로그램 : 논리식 집합
- 논리식은 명제나 술어로 나타냄.
ㄴ 술어는 인수를 받을 수 있음.
ㄴ 상세설명)
명제 : 딱 주어진, 정해진 틀만 가능.
술어 : 변수 개념.
ex) 모든 x에 대해서 x는 뭐다.
x가 뭐라면 참이 되고, x가 또 다른 값이라면 거짓이 된다. ... --> 이런 식으로 술어논리...
논리언어에서는 명제 혹은 술어를 다 표현할 수 있음.
ex) Prolog
// [논리형 언어는 어떤 방식으로 작동하는가]
puppy(happy). // 술어논리 : 'happy라고 하는 것은 강아지이다.' (정의)
safe(happy). // 'happy란 안전하다.' (정의)
pet(X) :- puppy(X), safe(X). // 애완동물(pet)이 뭔지 정의 :
// X라고 하는 것이 애완동물이 되려면, X는 강아지여야 되고, 그 X는 안전해야 한다 는 조건을 만족해야함.
실행결과)
? - pet(X). // 애완동물 중에 뭐가 있는지, X로 어떤 것이 가능한지 알려달라.
X = happy. // X로는 happy가 가능하다. (앞서 정의된 것을 바탕으로 참인 것을 가르쳐줌)
// happy는 강아지이기도 하고, 안전하기도 하니까, happy는 애완동물(pet)이 맞다.
// 최대공약수 계산 - gcd 함수 정의
gcd (U, 0, U). // 어떤 값하고 0이 들어오면, 어떤 값 하나를 최대공약수라고 알려주면 됨.
gcd(U, V, X) :- V > 0, Y is U mod V, gcd(V, Y, X). // 0이 아닌 두 가지 값이 나오는 경우에는
// 최대공약수가 X라고 정의해야하는데, 누가 X가 될 수 있느냐?
// 유클리드 알고리즘에서 U하고 V가 들어왔으면 두 U,V의 최대공약수란
// V하고, U를 V로 나눈 나머지 값 Y,
// 이 둘의 최대공약수와 같다는 것을 활용.
실행결과)
? - gcd(126, 312, X). // gcd라는 함수를 쓸건데, 126과 312 값을 줄테니까, 그걸 만족하는 최대공약수 X가 뭔지 알려줘.
X = 6 // 논리에 따라 그것을 만족하는 최대공약수 X는 6이다. ==> 논리를 통해서 계산이 가능하다 :)
?- gcd(126, 312, X).
X = 6
8. 프로그래밍 패러다임의 특징
1) 객체지향 패러다임 : 객체 사이의 통신을 통해 계산을 표현
2) 함수형 패러다임 : 함수의 적용을 통해 계산을 표현
3) 논리 패러다임 : 논리식의 진위를 증명하는 과정을 통해 계산을 표현
'Programming > Computer Science Fundamentals' 카테고리의 다른 글
[빅데이터의 이해] 3. 빅데이터의 활용1 (0) | 2021.09.09 |
---|---|
[빅데이터의 이해] 2. 빅데이터의 정의2 (0) | 2021.09.09 |
[빅데이터의 이해] 1. 빅데이터의 정의 1 (0) | 2021.09.09 |
[프로그래밍 언어론] 4. 구문론과 의미론 (0) | 2021.09.09 |
[프로그래밍 언어론] 2. 프로그램 언어의 발전 및 동작원리 (0) | 2021.09.07 |
[프로그래밍 언어론] 1. 프로그래밍 언어 소개 (0) | 2021.09.07 |
[운영체제] 운영체제의 구성, 프로세스, 쓰레드 (0) | 2021.04.08 |
[데이터베이스시스템] ER모델 (2장. 데이터베이스 모델링) (2) | 2021.04.01 |