Software Engineering

Imperative 명령형, Declarative Programming 선언형 프로그래밍

남희정 2023. 9. 9. 03:10

이전에 공부했던 키워드이지만 명확하게 한마디로 정의할 수 없어서 복습을 위해 다시 공부해본다!


Programming Paradigms

Programming Paradigms 프로그래밍 패러다임

Paradigm은 어떤 문제를 해결하거나 어떤 작업을 수행하는 방법

어떻게 프로그래밍을 할 것인가?

Programming Paradigm은 특정 프로그래밍 언어를 사용하여 문제를 해결하는 접근 방식, 또는 특정 접근 방식에 따라 사용할 수 있는 도구와 기술을 사용하여 문제를 해결하는 방법이다.

프로그래밍 언어는 알려진 것이 많지만 모두 구현할 때 몇 가지의 전략을 따르는데, 이 방법론/전략이 패러다임이다.

 

프로그래머에게 프로그래밍 관점을 갖게 하고 코드를 어떻게 작성할지 결정하는 역할을 한다. 새로운 프로그래밍 패러다임을 통해서 새로운 방식으로 생각하는 법을 배우게 되고, 이를 바탕으로 코드를 작성하게 된다.

프로그래밍 패러다임은 방법과 목적에 따라 재 분류된다.

 

✶ 절차적 프로그래밍, 객체지향 프로그래밍, 함수형 프로그래밍만 다룰 것이다 👽

Imperative vs Declarative

Imperative Programming 명령형 프로그래밍

How to do things

▪️ 가장 오래된 프로그래밍 패러다임 중 하나

▪️ Statements

▪️ 명령문을 사용하고 컴퓨터에 작업 지시를 한다.

▪️ 기계 아키텍처의 동작 방식과 밀접한 관계가 있다.

변수, 메모리, 레지스터 등과 같은 기계 아키텍처의 하드웨어 요소들을 직접적으로 다루며, 프로세서의 상태 변경과 메모리 접근을 명령어로 구체적으로 제어할 수 있다.

▪️ Von Neumann 폰 노이만 아키텍처 기반

헝가리 출신의 미국 수학자인 존 폰 노이만(John von Neumann)이 프로그램 내장 방식 컴퓨터(stored program computer)를 발표했다. 폰 노이만 구조(Von Neumann Architecture)라고도 불리는 프로그램 내장 방식은, 메모리에 프로그램과 데이터를 넣고 차례로 불러내 처리하는 방식으로 오늘날에도 쓰이고 있는 개념이다.

프로그램 저장 방식이 고안되기 이전의 모든 기계들은 하나의 목적 혹은 역할을 하도록 고안되었으나, 이 방식이 고안된 후 컴퓨터는 어떤 프로그램을 저장해서 실행하느냐에 따라 그 기능이 달라지며 컴퓨터의 범용성의 원천이 되었다. 

인출(fetch) → 해석(decode) → 실행(execute), CPU는 이러한 주기를 반복해서 실행한다.

Fortran, Basic, C와 같은 명령형 언어는 폰 노이만 모델 컴퓨터의 연산을 모방하거나 추상화하여 발전하였다.

따라서 이 언어들은 그 언어 내에서 폰 노이만 모델 컴퓨터의 특징을 많이 가지고 있다.

1. 순차적 명령어 실행

2. 메모리 위치를 나타내는 변수 사용

3. 배정문을 사용한 변수 값 변경

▪️ 프로그램은 초기 상태에서 시작하여 명령어를 순차적으로 실행하고, 각각의 명령어는 변수의 값을 변경하거나 조건에 따라 분기할 수 있다.

1️⃣ Procedural programming 절차적 프로그래밍

절차는 프로시저 Procedural를 이용한다는 의미.

🧑‍🏫 프로시저란, 특정 행동 혹은 목표를 수행하기 위한 일련의 작업이자 순서. 

▪️ 최종 기능(목표)를 달성하기 위해, 작은 규모의 함수(function)를 활용한다.

▪️ C, FORTRAN, Pascal, Basic, COBOL, ALGOL

▪️ 메모리의 값을 바꾸는 Side effect(함수나 표현이 변수의 값을 바꿈) 기반

▪️ 전체가 유기적으로 연결되도록 만든다.

▪️ 함수로부터 데이터를 받아서 기능을 구현하는 방식

▪️ 컴퓨터의 작업 처리방식과 유사하여 상대적으로 더 빠르다.

▪️ 순서와 흐름을 먼저 세우고 필요한 자료구조와 함수들을 설계하는 방식

▪️ 프로그램이 무슨 일을 하는가? (기능적 가치)

▪️ Top-down 하향식 접근 방식

▪️ 각 코드의 순서가 민감하게 연결되어있어 규모가 커지고 복잡도가 올라갈수록 유지보수 및 분석에 어려움이 있다.

▪️ 순서, 기능 측면에 오류가 생길 경우 올바르지 않은 결과가 도출된다.

 

순차적 프로그래밍과 착각하면 안됨.

순차적 프로그래밍과 절차적 프로그래밍

2️⃣  Object-Oriented Programming 객체지향 프로그래밍

절차적 프로그래밍의 한계점을 보완하고자 등장! 데이터 그 자체로는 구조화시키지 못했던 프로시저 방식.

🧑‍🏫 함수보다 데이터를 표현하는 객체 중심으로 프로그래밍하며 객체간의 유기적 동작을 한다.

▪️ 객체 간의 상호작용을 중시, 문제 해결을 위해 객체를 생성한 수 그들 간의 조합으로 해결법을 찾는다.

▪️ C++, Java, Python, C#

▪️ 가장 작고 기본적인 entity는 객체.

▪️ 객체는 데이터(속성)와 해당 데이터를 처리하는 메서드(동작)로 이루어져 있다.

데이터는 객체의 상태를 나타낸다. 메서드는 상태를 변경하거나 해당 객체에 관련된 작업을 수행한다. 메서드는 클래스에서 정의되고 객체의 행동을 정의한다.

▪️ Bottom-Top 상향식 접근 방식

▪️ 데이터 캡슐화와 상속이라는 개념이 사용된다.

▪️ 자료 구조와 이를 중심으로 모듈을 먼저 설계한 다음 실행 순서와 흐름을 조합하는 방식

▪️ 모든 종류의 연산은 객체에서만 수행된다.

▪️ 오늘날 존재하는 거의 모든 종류의 문제를 처리할 수 있다.

▪️ 현실세계의 어떤 대상을 모델링하는가?

▪️ 기능보다 데이터가 더 중요하다.

객체? 주체에 반대되는 말. 주체의 관점으로 실체를 바라볼 때. 실세계에 존재하거나 생각할 수 있는 것 전부.
이는 속성과 행위로 이루어져 있는데, 프로그래밍에선 변수, 메서드로 이루어져있다.

 

절차적 vs 객제지향

Declarative Programming 선언형 프로그래밍 

What to do

목표를 명시하고 알고리즘을 명시하지 않는 것

🧑‍🏫 부작용이 없고 변경 가능한 변수가 포함되어 있지 않다.

선언형 안에 명령형이 있다. 🤔 내부에 로직으로 구성되어 있는 것..!

▪️ 논리, 함수, DB로 나뉜다.

▪️ 제어 흐름 보다 계산 논리를 표현하는 프로그램을 작성한다.

▪️ 표현식을 사용, 표현식은 값으로 평가된다.

▪️ 표현식은 입력 자체에만 의존하여 입력을 받고 출력을 제공하는 데에 중점을 둔다. 함수형에서는 순수함수라고 한다.

▪️ 코드의 순서가 중요하지 않아질수록 더욱 선언적이게 된다. 순서 의존도가 없다.

 

// 명령형 방식으로 배열의 각 요소를 제곱하는 예제
const numbers = [1, 2, 3, 4, 5];
const squaredNumbers = [];

for (let i = 0; i < numbers.length; i++) {
  squaredNumbers.push(numbers[i] * numbers[i]);
}

console.log(squaredNumbers); // [1, 4, 9, 16, 25]

// 선언형 방식으로 배열의 각 요소를 제곱하는 예제
const numbers = [1, 2, 3, 4, 5];

const squaredNumbers = numbers.map((number) => number * number);

console.log(squaredNumbers); // [1, 4, 9, 16, 25]

 

선언형하면 제일 대표적으로 함수형 프로그래밍을 꼽는다.

✳️  Functional Programming 함수형 프로그래밍

함수 자체가 일급 객체가 되는 프로그래밍 기법

▪️ 상태 값을 지니지 않는 함수들의 연속

▪️ 값의 연산 및 결과 도출 중심으로 코드 작성이 이루어진다.

▪️ 함수는 인자로 받은 값을 별도로 저장하지 않고, 간결한 과정으로 처리하고 매핑하는 데에 목적을 둠.

▪️ 데이터형에 구애 받지 않음

▪️ 상수 사용을 선호한다.

▪️ 순수 함수 구성을 기반으로 하는 선언적 패러다임

▪️ 1930년대 수학적 논리 체계인 람다 미적분을 기반으로 하는 Turing-complete 언어.

▪️ Scheme, Haskell, ML, Erlang

 

The central model for the abstraction is the function which are meant for some specific computation and not the data structure. Data are loosely coupled to functions. The function hide their implementation. Function can be replaced with their values without changing the meaning of the program.

 

➡️ 추상화의 중심 모델은 특정한 계산을 위해 만들어진 함수(function)이다. 데이터는 함수와 느슨하게 결합된다. 함수는 자신의 구현을 숨긴다. 함수는 그들의 값으로 대체될 수 있고, 이로 인해 프로그램의 의미가 변하지 않는다.

 

패러다임의 진화

 

어떤 패러다임이 좋은가에 대해 말하는 것이 아님을 명심!

 


[Imperative vs Declarative Programming]

[선언형, 명령형 코드 그리고 추상화]

[[CS/Basic] 마침내, 객체지향 프로그래밍 (OOP, Object-Oriented Programming)]

[Difference Between Imperative and Declarative Programming]

[Programming Paradigms: A must know for all Programmers]

[객체지향과 절차지향]

[Programming paradigm]