여기서 프로시저란?
- 프로시저는 루틴이나 서브루틴의 원형으로 연속된 computational 스텝으로 구성되어 있다.
- 일반적으로는 명령문을 절차적으로 기술해 놓은 것이라고 보면 될 것 같다.
- 함수랑 비교를 해본다면, 함수는 프로시저의 각 절차를 수행하기 위해 필요한 기능이라고 볼 수 있겠다.
- 프로시저는 특정 작업을 수행하고, 함수는 특정 계산을 수행한다.(인풋을 넣으면 한개의 아웃풋이 나오는)
- 프로시저는 리턴값을 여러개 가질 수 있고, 함수는 리턴 값을 하나만 가질 수 있다.
- 참고 링크 : https://en.wikipedia.org/wiki/Imperative_programming
- 참고로, 서브루틴이란 일반적으로 아무것도 accept하지 않고 아무것도 리턴하지 않는 function을 의미한다.
대부분의 프로그래밍 언어에서 서브루틴과 function을 명확히 구분하지는 않는다고한다.
- 서브루틴은 function이라고 불리긴하는데, function은 subroutine이라 무조건 부를 수 있는건 아니다.
- 루틴이랑은 무슨 차이가 있나 싶어서 알아보았는데, 루틴 안에서 하위개념으로 동작하는게 서브루틴이라고 볼 수 있겠다.
- 루틴이 메인 프로그램이라면, 그 안에서 돌아가는 function이 서브루틴이 될 수 있다.
- 프로시저 호출은 프로그램의 어느 시점이던 간에 가능하다. (자기 자신 혹은 타 프로시저를 호출할 수 있다.)
- 참고 링크 :
→ 개괄적으로 이 글 보면 도움이 된다.
객체지향에는 4가지 개념이 존재한다.
다들 한번쯤 생각해봤듯이, 절차적 프로그래밍과 객체지향 프로그래밍은 무엇이 다른지 고민해보았다.
참고 :
명령형 프로그래밍은 프로그램을 짤 때 어떤 방법으로 해야 하는지를 나타내지만, 선언형 프로그래밍은 내가 무슨 프로그램을 짜야하는지를 설명하는 방법이다.
명령형 프로그래밍은 알고리즘을 명시하고 목표는 명시하지 않는 데 반해 선언형 프로그래밍은 목표를 명시하고 알고리즘을 명시하지 않는다.
선언형 프로그래밍을 이해하다보면, 이런 의문이 들 수 있다. 아래는 선언형 방식의 예시이다.
// 명령형 방식 (HOW)
function double (arr) {
let results = [];
for (let i = 0; i < arr.length; i++) {
results.push(arr[i] * 2)
}
return results;
}
// 선언형 방식 (WHAT)
function double (arr) {
return arr.map((item) => item * 2)
}
이렇게 보면 선언형 방식도 map이란 built in 함수 사용해서 간결하게 짠 방법 아닌가? map도 결국 코드를 까보면 위 방식처럼 되어 있는거면 선언형 방식도 본질적으로 명령형 방식 아닌가? 라는 생각이 들 수 있다.
기본적인 컨셉은 아래와 같다.
1. 변경 가능한 상태를 불변상태(Immutable)로 만들어 Side Effect를 없애자.
2. 모든 것은 객체이다.
3. 코드를 간결하게 하고 가독성을 높여 구현할 로직에 집중 시키자.
4. 동시성 작업을 보다 쉽게 안전하게 구현 하자.
참고
- https://medium.com/@lazysoul/함수형-프로그래밍이란-d881230f2a5e
- https://sungjk.github.io/2017/07/17/fp.html
- https://codechaser.tistory.com/81
- https://easywritten.com/post/real-advantages-of-functional-programming/
데이터를 중심으로 프로그래밍하는 방식이다.
OOP도 데이터를 중심으로 프로그래밍하긴 하지만, 반응형 프로그래밍은 데이터의 흐름 추적을 중점적으로 두는 프로그래밍 방식이다.
함수형 프로그래밍에 기반을 두고 있는데, 함수형 프로그래밍이 가진 '불변상태'를 기초로 둔다.
반응형 프로그래밍에서는 변수의 값을 바꾸면 해당 변수를 참조하는 모든 식들이 연쇄적으로 재평가되면서 스스로의 값을 갱신한다. 프로그래머가 명시적으로 재계산 명령을 내리지 않는다.
구체적으로는 모든 데이터를 "스트림"으로 보는데, 여기서 스트림이란 시간순으로 발생하는 이벤트의 나열이다.스트림은 value, error, complete 의 각 시그널을 발생시킬 수 있다.
기본 베이스는 Observer Pattern이다. 하나의 데이터 스트림을 감시(구독)하는 대상이 있다면, 데이터 스트림의 변화가 발생할 경우 변화 전파가 일어나는데 감시하는 대상은 이를 감지하고 필요한 작업을 하게 된다.
즉, 데이터가 변경될 때마다 관련된 로직을 일일히 호출하는 것이 아니라, 데이터 스트림이 존재하고 이를구독하는 곳에서 변화에 따라 알아서 처리하는 하겠다는 것이다.
a = 10;
b = 20;
c = a + b;
// c: 30
a = 20;
// c: 30
일반적인 프로그래밍의 경우 a값을 변경해도 c의 결과는 그대로 있다.반응형의 경우 조금 다르다.
a = 10;
b = 20;
c = a + b;
// c: 30
a = 20;
// c: 40
반응형의 경우 모든 데이터를 스트림으로 보고 스트림의 데이터가 변화되면 이를 전파하여 해당 데이터 스트림을 구독하고 있는 곳도 영향을 받는다.
이 글에 정리한 내용은 입문 수준이기 때문에 대략 패러다임이 어떤 것인지는 이해했을 것이다. 필요한 내용은 추가로 찾아보길 권한다.