Featured image of post 6. 함수형 프로그래밍

6. 함수형 프로그래밍

2부 - 벽돌부터 시작하기: 프로그래밍 패러다임

함수형 프로그래밍이라는 개념은 프로그래밍 그 자체보다 앞서 등장했다.

이 패러다임에서 핵심이 되는 기반은 람다(Lambda) 계산법으로 안론조 처치가 1930년대에 발명했다.

불변성과 아키텍처

일반적인 언어들과 달리 함수형 언어에서는 변수가 한번 초기화되면 절대로 변경되지 않는다.

가변 변수로 인해 경합 조건, 교착상태 조건, 동시 업데이트 문제가 발생하는데, 만약 어떠한 변수도 갱신되지 않는다면 경합 조건이나 동시 업데이트 문제가 발생하지 않는다.

락(lock)이 가변적이지 않다면 교착상태도 일어나지 않는다.

동시성 애플리케이션에서 마주치는 모든 문제, 즉 다수의 스레드와 프로세스를 사용하는 애플리케이션에서 마주치는 모든 문제는 가변 변수가 없다면 절대로 생기지 않는다.

불변성은 저장 공간이 무한하고 프로세서의 속도가 무한히 빠르다면 보장 가능하지만 그럴 수 없으므로 어느정도 타협이 필요하다.

가변셩의 분리

불변성과 관련하여 가장 주요한 타협 중 하나는 애플리케이션 또는 애플리케이션 내부의 서비스를 가변 컴포넌트와 불변 컴포넌트로 분리하는 일이다.

불변 컴포넌트에서는 순수하게 함수형 방식으로만 작업이 처리되며, 어떤 가변 변수도 사용되지 않는다.

불변 컴포넌트는 변수의 상태를 변경할 수 있는, 죽 순수 함수형 컴포넌트가 아닌 하나 이상의 다른 컴포넌트와 서로 통신한다.

상태 변경과 트랜잭션 메모리

상태 변경은 컴포넌트를 갖가지 동시성 문제에 노출하는 꼴이므로, 흔히 트랜잭션 메모리와 같은 실천법을 사용하여 동시 업데이트와 경합 조건 문제로부터 가변 변수를 보호한다.

트랜잭션 메모리는 트랜잭션을 사용하거나 도는 재시도 기법을 통해 변수를 보호한다.

애플리케이션을 제대로 구조화하려면 변수를 변경하는 컴포넌트와 변경하지 않는 컴포넌트를 분리해야한다.

그리고 이렇게 분리하려면 가변 변수들을 보호하는 적절한 수단을 동원해 뒷받침해야한다.

현명한 아키텍트라면 가능한 한 많은 처리를 불변 컴포넌트로 옮겨야 하고, 가변 컴포넌트에서는 가능한 한 많은 코드를 빼내야 한다.

이벤트 소싱

이벤트 소싱은 상태가 아닌 트랜잭션을 저장하자는 전략이다.

상태가 필요해지면 단순히 상태의 시작점부터 모든 트랜잭션을 처리한다.

이 전략은 많은 저장 공간을 필요로 하지만 현재는 저장 공간을 충분히 확보할 수 있다.

  • 데이터 저장소에서 삭제되거나 변경되는 것이 하나도 없으므로, 결과적으로 애플리케이션은 CRUD가 아닌 그저 CR만 수행한다.
  • 데이터 저장소에서 변경과 삭제가 전혀 발생하지 않으므로 동시 없데이트 문제 또한 일어나지 않는다.

저장 공간과 처리 능력이 충분하면 완전한 불변성을 갖도록 만들 수 있고, 따라서 완전한 함수형으로 만들 수 있다.

  • 버전 관리 시스템이 정확히 이방식으로 동작한다.

결론

  • 구조적 프로그래밍은 제어흐름의 직접적인 전환에 부과되는 규율이다.
  • 객체 지향 프로그래밍은 제어흐름의 간접적인 전환에 부과되는 규율이다.
  • 함수형 프로그래밍은 변수 할당에 부과되는 규율이다.

세 패러다임 모두 무언가를 하지 못하게 제한하고 있으며, 코드를 작성하는 방식의 형태를 한정시킨다.

지난 반세기 동안 우리가 배운 것은 해서는 안되는 것에 대해서이다.

도구는 달라졌고 소프트웨어도 변했지만, 소프트웨어는 순차, 분기, 반복 참조로 구성된다는 것은 변하지 않았다.