멘토링에서 공부해야할 키워드는 절차지향 프로그래밍과 선언형 프로그래밍 두개인데, 넓고 깊게 알아보기 위해 명령형 vs 선언형으로 정했다. 굉장히 헷갈릴 수 있는 부분이라 열심히 공부해보겠다.


Programming Paradigms

Paradigm은 어떤 문제를 해결하거나 어떤 작업을 수행하는 방법.
Programming paradigm은 특정 프로그래밍 언어를 사용하여 문제를 해결하는 접근 방식, 또는 특정 접근 방식에 따라 사용할 수 있는 도구와 기술을 사용하여 문제를 해결하는 방법이다.
프로그래밍 언어는 알려진 것이 많지만 모두 구현할 때 몇 가지의 전략을 따르는데, 이 방법론/전략이 패러다임이다.

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

Imperative programming

명령형 프로그래밍 How to do things

  • 가장 오래된 프로그래밍 패러다임 중 하나
  • statements
  • 명령문을 사용하고 컴퓨터에 작업 지시를 한다.
  • 기계 아키텍처와 밀접한 관계가 있다.
    ➡️ 기계 아키텍처의 동작 방식과 밀접하게 관련이 있다는 것.
    변수, 메모리, 레지스터 등과 같은 기계 아키텍처의 하드웨어 요소들을 직접적으로 다루며, 프로세서의 상태 변경과 메모리 접근을 명령어로 구체적으로 제어할 수 있다.
  • Von Neumann 폰 노이만 아키텍처가 기반.
  • 실행 단계에서 명령어를 사용하여 상태를 변경하고 작업을 수행하는 프로그래밍 스타일
  • 주요 초점을 목표를 달성하는 방법에 있다.
  • 프로그래머가 작업의 순서와 세부 사항을 명령어로 명시적으로 제어
  • 프로그램은 초기 상태에서 시작하여 명령어를 순차적으로 실행하고, 각각의 명령어는 변수의 값을 변경하거나 조건에 따라 분기할 수 있다.

예시

#include <stdio.h>

int main() {
   int number = 10;

   printf("현재 숫자: %d\n", number);

   number = number + 5;
   printf("변경된 숫자: %d\n", number);

   if (number > 10) {
      printf("숫자는 10보다 큽니다.\n");
   } else {
      printf("숫자는 10보다 작거나 같습니다.\n");
   }

   return 0;
}

위의 코드에서, number라는 변수의 초기값은 10이다.
프로그램은 number의 값을 5만큼 증가시키고, 그 후에 조건에 따라 메시지를 출력한다.
이때, number 변수의 값을 변경하여 상태를 변경하고, 분기문을 사용하여 프로그램의 흐름을 제어한다.
이와 같이 imperative programming은 명령어에 의해 상태가 변화하고, 순차적으로 작업을 수행하는 프로그래밍 패러다임이다.

특징

  • 구현이 매우 간단하다!
  • 루프, 변수 등이 포함되어있다.
  • 복잡한 문제를 해결할 수 없다
  • 효율성과 생산성 저하
  • 병렬 프로그래밍이 불가능하다.

Procedural programming

절차지향 프로그래밍

  • 절차적 접근 방식과 명령적 접근 방식에는 차이가 없다.
  • 코드를 재사용할 수 있는 기능이 있으며 재사용성 때문에 사용 당시 큰 이점이었다.
  • 초기의 프로그래밍 방식, 일의 진행 순서대로 프로그래밍 하는 방법. (데이터 흐름에 기반한 프로그래밍)
  • 전체가 유기적으로 연결되도록 만든다.
  • 함수로부터 데이터를 받아서 기능을 구현하는 방식
  • 컴퓨터의 작업 처리방식과 유사하여 상대적으로 더 빠르다.
  • 순서와 흐름을 먼저 세우고 필요한 자료구조와 함수들을 설계하는 방식
  • 프로그램이 무슨 일을 하는가? (기능적 가치)
  • Top-down 방식
  • 각 코드의 순서가 민감하게 연결되어있어 규모가 커지고 복잡도가 올라갈수록 유지보수 및 분석에 어려움이 있다.

Examples of Procedural programming paradigm:

  • C : developed by Dennis Ritchie and Ken Thompson
  • C++ : developed by Bjarne Stroustrup
  • Java : developed by James Gosling at Sun Microsystems
  • ColdFusion : developed by J J Allaire
  • Pascal : developed by Niklaus Wirth

Object oriented programming

객체지향 프로그래밍

  • 모든 데이터를 객체로 취급, 객체가 처리 요청을 받았을 때, 객체 내부의 기능을 사용해 처리하는 방법.
  • 함수보다 데이터를 표현하는 객체 중심으로 프로그래밍하며 객체간의 유기적 동작을 한다.
  • 클래스와 객체의 집합으로 작성된다.
  • 가장 작고 기본적인 entity는 객체!
  • 모든 종류의 연산은 객체에서만 수행된다.
  • 오늘날 존재하는 거의 모든 종류의 문제를 처리할 수 있다.
  • 자료구조와 이를 중심으로 한 모듈들을 먼저 설계한 다음에 실행 순서와 흐름을 짜는 방식
  • 현실세계의 어떤 대상을 모델링하는가?
  • Bottom-up 방식을 지향
  • 독립성/신뢰성을 높게 만들어 놓으면 이후 재사용 (기간, 비용 감소)
  • 처리 속도가 상대적으로 느리다.
  • 설계에 많은 시간이 소요된다.

특성
1. 캡슐화 : 데이터와 함수를 하나로 묶는 것.
2. 정보은닉 : 캡슐화에서 가장 중요한 개념, 다른 객체에게 자신의 정보를 숨기고 연산만을 통해 접근 허용. (세부적인 내용을 숨기고 응집도을 높여 결합도를 낮춘다.)
3. 추상화 : 객체의 중요한(공통) 속성에만 중점을 두고 모델화
4. 상속성 : 이미 정의된 클래스의 모든 속성, 연산을 물려받는다.
5. 다형성 : 메세지에 의해 클래스가 연산을 수행하게 될 때 각 객체가 갖고 있는 고유의 방법으로 응답할 수 있는 능력. (오버라이딩)

이 특성들에 대해선 깊이있는 공부가 필요하기에 추후에 정리하겠다!

Examples of Object Oriented programming paradigm

  • Simula : first OOP language
  • Java : developed by James Gosling at Sun Microsystems
  • C++ : developed by Bjarne Stroustrup
  • Objective-C : designed by Brad Cox
  • Visual Basic .NET : developed by Microsof
  • Python : developed by Guido van Rossum
  • Ruby : developed by Yukihiro Matsumoto
  • Smalltalk : developed by Alan Kay, Dan Ingalls, Adele Goldberg

Declarative programming

선언형 프로그래밍 What to do

  • 논리, 함수, DB로 나뉜다.
  • 제어 흐름 보다 계산 논리를 표현하는 프로그램을 작성한다.
  • expressions.
  • 표현식을 사용, 표현식은 값으로 평가된다.
  • 표현식은 입력 자체에만 의존하면서 입력을 받고 출력을 제공하는 데 중점을 둔다. 이러한 표현을 함수형 프로그래밍에서는 순수함수라고 한다.
  • 코드는 원하는 결과를 컴퓨터에 선언하여 입력에 따라 결과를 평가하는 식을 기반으로 함.

Database/Data driven programming
Logic programming

둘은 제외하겠다.

Functional programming

함수형 프로그래밍

  • 함수 자체가 일급객체가 되는 프로그래밍 기법 (객체지향에서는 클래스 또는 Object가 일급객체이다.)
  • 상태 값을 지니지 않는 함수들의 연속 (객체지향에서는 프로그램에서 상호작용하는 객체들의 집합)
  • 값의 연산 및 결과 도출 중심으로 코드 작성이 이루어짐
  • 함수는 인자로 받은 값을 별도로 저장하지 않고, 간결한 과정으로 처리하고 매핑하는 데에 목적을 둠.
  • 객체지향보다 코드가 간결하여 사이드이펙트를 미연에 방지한다.
  • 데이터형에 구애받지 않는다.
  • 외부 상태를 변경하거나 콘솔 로그, 파일 저장, 데이터베이스 레코드 로드와 같은 외부 동작을 유발하는 것을 Side effect라고 함.
  • 어떤 값의 값을 변경하는 것을 변이라고 한다. 함수형 프로그래밍에서는 항상 상수를 사용하는 것을 선호한다.
  • 함수형 프로그래밍은 순수 함수 구성을 기반으로 하는 선언적 패러다임
  • 1930년대의 수학적 논리 체계인 람다 미적분을 기반으로 하는 Turing-complete 언어.
// 명령형
function mult2 (arr){
    let results = []
    for(let i=0; i<arr.length; i++{
    	results.push(arr[i]*2);
    }
    return result
}

// 선언형
function mult2(arr){
    return arr.map((v) => item *2);
}

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.

외국 사이트를 번역해서 이해하다보니 확실히 하기 어려워서 ChatGPT에게 쉽게 설명해달라고 요청해보았다. + 좀 더 쉽게 이해가 가도록 내가 각색해보았다. 이해가 안되는 분들에게 도움이 되길 바람.

커피를 만드는 커피 머신을 사용한다고 가정을 하자!
커피머신은 다양한 기능을 갖고 있다. (에스프레소, 아메리카노, 아이스 아메리카노, 카페라떼 등)
함수형 프로그래밍은 데이터 구조가 아닌 특정 연산을 위해 함수를 사용한다고 했다. 여기서 특정 연산을 커피머신의 작동에 필요한 다양한 기능이라고 생각해본다.
함수는 데이터 구조와 느슨하게 결합된다고 했다. 이것은 함수는 데이터의 형태나 구체적인 내용에 대해 크게 신경쓰지 않는다는 것, 함수는 입력을 받고 결과를 출력하는 역할만 하는 것이다.
커피머신에서 결과물인 "아메리카노"(함수)를 볼 때, 함수는 커피머신에 필요한 데이터인 커피 가루와 물를 입력 받고 결과물을 출력한다.
함수의 구현 내용을 숨겨지고 함수를 이용해서 원하는 작업을 수행할 수 있는 것이다.

아메리카노를 얻고 싶은 나는 아메리카노가 어떤 순서로 만들어지는지, 안에 어떤 재료가 들어가는지 보다 내가 먹고 싶은 '무엇'을 얻는 것인지에 초점을 맞춘 것!!!!

Examples of Functional programming paradigm:

  • JavaScript : developed by Brendan Eich
  • Haskell : developed by Lennart Augustsson, Dave Barton
  • Scala : developed by Martin Odersky
  • Erlang : developed by Joe Armstrong, Robert Virding
  • Lisp : developed by John Mccarthy
  • ML : developed by Robin Milner
  • Clojure : developed by Rich Hickey

결론

명령형과 선언형을 보았을 때 과정 중심형이냐 결과 중심형이냐로 나눠지는 걸 알게 되었다.
이전에 JS 구조를 이해할 때 메모리를 아끼기 위해 재사용성, 변수가 저장되는 방식을 보았었다.
"상수를 아껴야하는 것 아닌가?" 상수를 많이 쓰게 되면 메모리를 차지하는 게 많아질텐데! 했었다. 재사용성에 중심을 둘 순 있지만 그것만큼 발전된 하드웨어가 있기 때문에 이 시대에선 이제 상태의 안정성을 확보하고 싶은 것, 그리고 그것이 프로그래밍에서 제일 핵심목표라는 것..!
함수형 프로그래밍에서 언급된 불변하는 상태에 대해서 Stackoverflow에도 비슷한 얘기가 올라와있는데 무려 2009년 게시물이다.
how-can-you-do-anything-useful-without-mutable-state
Just about every user application I can think of involves state as a core concept.
흔적을 찾아보는 재미가 있다

멘토링에서 중요하게 여겼던 '상태'는 노션에 따로 정리해보겠다.


참조 ✅

2개의 댓글

comment-user-thumbnail
2023년 7월 19일

소중한 정보 잘 봤습니다!

1개의 답글