본문 바로가기
Apple/RxSwift

[RxSwift] 선언형 프로그래밍

by 어멘드 2023. 8. 8.
반응형

RxSwift는 함수형 프로그래밍 패러다임을 따른다. 그리고 함수형 프로그래밍은 선언형 프로그래밍 패러다임을 따른다. 선언형 프로그래밍 패러다임을 공부해보자.

 

선언형 프로그래밍의 정의

위키피디아의 정의를 따르면 다음과 같다.

 프로그램이 어떤 방법으로 해야 하는지를 나타내기보다 무엇과 같은지를 설명하는 경우에 "선언형"이라고 한다. 간단히 말하여, 명령형 프로그램은 알고리즘을 명시하고 목표는 명시하지 않는 데 반해 선언형 프로그램은 목표를 명시하고 알고리즘을 명시하지 않는 것이다.

 선언형 프로그래밍은 구체적인 '방법'이 아니라 '목표' 자체를 설명하는 것이라고 한다. 반대로 '방법'을 설명하는 경우 명령형 프로그래밍 패러다임이라고 부른다. 그러므로 선언형 프로그래밍을 이해하기 위해서는 명령형 프로그래밍도 함께 살펴보아야 한다.

 

선언형 코드 vs. 명령형 코드

 글만으로는 잘 이해되지 않아서 여러 포스팅을 돌아다니면서 코드를 찾아보았다. 가장 많이 등장하는 예시는 다음과 같은 코드이다.

// 명령형
func imperativeAddOne(_ array: [Int]) -> [Int] {
    var newArray: [Int] = []
    
    for element in array {
        newArray.append(element + 1)
    }
    
    return newArray
}

// 선언형
func declarativeAddOne(_ array: [Int]) -> [Int] {
    return array.map { $0 + 1 }
}

배열의 모든 원소에 1을 더해주는 프로그램을 만들자. 명령형 프로그래밍으로는 다음과 같이 구현할 수 있다.

1. 새로운 빈 배열 newArray를 만든다.
2. 주어진 배열의 모든 원소를 순회하면서
3. 각 원소에 1을 더한 정수를 newArray에 추가한다.

반면에 선언형 프로그래밍은 그냥 각 원소에 1이 더해진 배열을 리턴해주고 있다.

 정리해보자면 명령형 프로그래밍은 우리가 원하는 것을 얻기 위한 방법 즉 "새로운 빈 배열 newArray를 만들고, 주어진 배열의 모든 원소를 순회하면서 각 원소에 1을 더한 정수를 newArray에 추가한 뒤, newArray를 줘"라고 말하는 것이고, 선언형 프로그래밍은 우리가 원하는 것 그대로 "각 원소에 1이 더해진 배열을 줘"라고 하는 것이다.

 

선언형과 명령형의 차이는 추상화 정도?

 array.map { $0 + 1 } 부분을 '그냥 각 원소에 1이 더해진 배열'이라고 말할 수 있는 이유는, 각 원소에 1을 더해주는 방법에 해당하는 코드가 map이라는 함수로 추상화되어있기 때문이다.

 여기서 다음과 같은 의문점이 생겼다. 그럼 함수로서 추상화되어 구현부가 숨겨지면 선언형 프로그래밍인 것일까? 그럼 명령형 프로그래밍 언어와 선언형 프로그래밍 언어를 나누는 기준은 추상화 수준인가? 똑같은 질문글을 여기에서 발견하였는데 가장 많은 추천을 받은 답변을 정리해보면 다음과 같다.

 

 선언형 프로그래밍 언어가 항상 더 높은 추상화 수준을 갖는 것은 아니다. 같은 정도의 추상화 수준을 가질 수도 있다. 따라서 선언형과 명령형을 구분하는 기준을 추상화 수준이라고 할 수 없다. 이번엔 코드 말고 현실세계의 예시를 살펴보자.

명령형: "달걀의 껍질을 벗겨서, 접시에 놓고, 오븐에 180도로 돌려주세요."
선언형: "오븐에서 180도로 구워진, 접시에 놓인 깐 달걀 주세요."

 이 예시에서 선언형이라고 더 추상화되어있지 않다. (두 문장이 약간 말장난처럼 느껴지는 것도 이 때문이다.) 이게 무슨 말이냐면, 달걀의 조리법(오븐 180도, 접시, 껍질까기)이 선언형에도 다 담겨야 한다는 뜻이다. 선언형이라고 해서 달걀 조리법을 알려주지도 않았는데 알아서 내가 원하는 대로 조리해오지는 않는다.

 즉 선언형과 명령형을 구분하는 기준은 표현 방식, 프로그램이 어떻게 표현되는가이다. 명령형은 일련의 단계로 표현하고, 선언형은 최종 목표 자체를 표현한다. 결국 돌고 돌아 다시 정의로 돌아오게 되었다.


레퍼런스

https://stackoverflow.com/questions/1784664/what-is-the-difference-between-declarative-and-imperative-paradigm-in-programmin
https://softwareengineering.stackexchange.com/questions/369269/is-it-possible-to-say-that-the-difference-between-imperative-programming-and-dec
https://ui.dev/imperative-vs-declarative-programming

반응형

'Apple > RxSwift' 카테고리의 다른 글

[RxSwift] 리액티브 프로그래밍  (0) 2023.08.12
[RxSwift] 함수형 프로그래밍  (0) 2023.08.08

댓글