해당 글은 쏙쏙 들어오는 함수형 코딩 책 내용을 기반으로 작성된 내용입니다.
💡 이번 장에서 살펴볼 내용
- 함수형 사고가 무엇인지 설명합니다.
- 다른 함수형 프로그래밍 책과 어떻게 다른지 알 수 있습니다.
- 함수형 프로그래머가 코드를 바라보는 특별한 방법을 알게 됩니다.여러분이 이 책을 계속 볼지 말지 감을 잡을 수 있습니다.
함수형 프로그램을 한마디로 설명하는 것은 어렵습니다. 함수형 프로그래밍은 학계나 산업 현장에서등 넓은 분야에서 쓰이고 있지만 많은 자료가 학계에서 만든 자료라 일반 개발자가 이해하기 어렵고 실용적이지 않습니다. 하지만 이 책은 실무에서 쓸 수 있는 내용을 다룹니다.
함수형 프로그래밍은 무엇인가요?
위키피디아에 정의된 내용을 요약하면 다음과 같습니다:
함수형 프로그래밍 (functional programming, FP), 명사
- 수학 함수를 사용하고 부수 효과를 피하는 것이 특징인 프로그래밍 패러다임입니다.
- 부수 효과 없이 순수 함수 (pure function) 만을 사용하는 프로그래밍 스타일입니다.
부수 효과
- 부수 효과란 함수에서 결괏값을 주는 것 외에 하는 행동을 말합니다.
- 함수가 리턴 값 이외에 하는 모든 일을 말합니다.
- 부수 효과는 함수를 부를 때마다 발생하기 때문에 문제가 될 수 있습니다.
- 대부분의 함수형 프로그래머는 불필요한 부수 효과를 최소화 하려고 합니다.
부수 효과가 발생하는 예
- 이메일 보내기
- 파일 읽기
- 불빛을 깜빡이기
- 웹 요청을 하기
- 자동차에 브레이크 밟기
순수 함수
- 순수 함수는 같은 인자를 넣으면 항상 같은 결과를 반환 하고 부수 효과가 없는 함수 입니다.
- 수학에서 사용되는 함수의 개념과 동일하기 때문에 순수 함수를 수학 함수라고 볼 수 있습니다.
- 순수 함수는 다루기 쉽고 이해하기 쉽기 때문에 함수형 프로그래머들이 중요하게 생각합니다.
정의에 따르면 함수형 프로그래머는 항상 부수 효과를 피하고 순수 함수만 사용해야 할 것 같지만, 실제 함수형 프로그래머는 부수 효과와 순수하지 않은 함수를 사용합니다.
실용적인 측면에서 함수형 프로그래밍 정의의 문제점
위키피디아에서 살펴본 함수형 프로그래밍의 정의는 학문적으로는 가치가 있을 지 모르지만 실제 프로그래밍을 하는 개발자에게 큰 도움이 되지 않습니다.
문제 1: 부수 효과는 필요합니다.
정의에 따르면 함수형 프로그래밍은 부수 효과를 피해야 하지만 부수 효과는 소프트웨어를 실행하는 이유입니다.
이메일을 전송하지 않는 이메일 전송 소프트웨어가 무슨 의미가 있을까요? 정의에는 부수 효과를 완전히 쓰지 말라는 것처럼 되어 있지만 필요할 때는 써야합니다.
문제 2: 함수형 프로그래밍은 부수 효과를 잘 다룰 수 있습니다.
함수형 프로그래밍 정의에는 순수 함수만 사용하라고 나와 있지만, 실제로 함수형 프로그래머는 순수하지 않은 함수도 사용합니다. 그리고 순수하지 않은 함수를 잘 다룰 수 있는 기술이 많이 있습니다.
문제 3: 함수형 프로그래밍은 실용적입니다.
함수형 프로그래밍으로 잘 만들어진 소프트웨어가 많이 있지만 정의에서는 함수형 프로그래밍이 수학적이라는 표현 때문에 시작하려는 사람에게 혼란을 줍니다. 다음은 위키피디아에서 함수형 프로그래밍의 정의를 보고 혼란스러워하는 관리자의 사례를 살펴봅시다.
함수형 프로그래밍 정의가 혼란스러운 관리자
함수형 프로그래밍을 학문적 지식이 아닌 기술과 개념으로 보기
함수형 프로그래밍은 학술적으로도 실용적으로도 많은 내용이 있습니다. 이 책에서는 학술적인 최신 연구 자료나 난해한 개념은 빼고 실제 함수형 프로그래밍을 쓰고 있는 프로그래머가 가진 기술과 생각의 흐름, 시각을 정리했습니다. 이 책을 쓰면서 함수형 프로그래밍의 중요한 개념은 객체 지향 프로그래밍이나 절차적 프로그래밍을 가리지 않고 모든 프로그래밍 언어에서 쓸 수 있다는 것을 알았습니다. 함수형 프로그래밍의 진정한 아름다움은 코드 어느 곳에나 적용할 수 있는 유익한 내용이라는 점입니다.
그럼 이제 함수형 프로그래머들이 입을 모아 중요하다고 말하는 기술인 액션과 계산, 데이터를 구분하는 일에 대해 살펴 봅시다.
액션과 계산, 데이터 구분하기
함수형 프로그래머는 직감적으로 코드를 액션, 계산 데이터 세 분류로 나눕니다.
아래 코드를 액션과 나머지 코드로 구분해보면 다음과 같습니다
// 별 표시가 있는 코드를 액션이라고 부르겠습니다.
{ "firstname": "Eric", "lastname": "Normand" } //사람에대한 정보
*sendEmail(to, from, subject, body) // 이메일을 보내는 코드
sum(numbers) //모든 숫자를 더하는 함수
*saveUserDB(user) //DB에 저장하면 다른 시스템에서 저장한 데이터를 볼 수 있습니다.
string_length(str) //같은 문자열을 넣으면 항상 같은 길이를 줍니다.
*getCurrentTime() //부를 때마다 다른 시간을 줍니다.
[1, 10, 2, 45, 3, 98] //숫자 리스트입니다.
함수형 프로그래머는 부를 때 조심해야 하는 코드를 구분합니다.
선을 하나 긋고 호출하는 횟수나 호출하는 시점이 중요한 함수는 위로 올려봅시다.
*sendEmail(to, from, subject, body) // 이메일을 보내는 코드
*saveUserDB(user) //DB에 저장하면 다른 시스템에서 저장한 데이터를 볼 수 있습니다.
*getCurrentTime() //부를 때마다 다른 시간을 줍니다.
--------------------------------------------------------------
{ "firstname": "Eric", "lastname": "Normand" } //사람에대한 정보
sum(numbers) //모든 숫자를 더하는 함수
string_length(str) //같은 문자열을 넣으면 항상 같은 길이를 줍니다.
[1, 10, 2, 45, 3, 98] //숫자 리스트입니다.
액션(선 위쪽에 있는 코드)은 호출하는 시점과 횟수에 의존합니다. 반면에 선 아래쪽에 있는 코드는 사용하기 쉽습니다. 예를 들어 sum 함수는 호출하는 시점이 중요하지 않습니다. 언제 호출해도 항상 같은 값을 주기 때문입니다. 호출하는 횟수 역시 중요하지 않습니다. 나머지 코드나 소프트웨어 외부에 영향을 주지 않기 때문에 여러 번 호출해도 상관없습니다.
함수형 프로그래머는 실행하는 코드와 그렇지 않은 코드를 구분합니다.
계산과 데이터는 둘 다 부르는 시점이나 횟수가 중요하지 않습니다. 계산과 데이터의 차이는 계산은 실행 가능하나 데이터는 그렇지 않습니다. 데이터는 정적이고 보이는 그대로 이지만 계산은 실행하기 전까지 어떻게 동작할지 알 수 없습니다.
액션: 액션은 부르는 시점에 의존
*sendEmail(to, from, subject, body) // 이메일을 보내는 코드
*saveUserDB(user) //DB에 저장하면 다른 시스템에서 저장한 데이터를 볼 수 있습니다.
*getCurrentTime() //부를 때마다 다른 시간을 줍니다.
--------------------------------------------------------------
계산: 계산은 입력값을 계산해 출력하는 것
sum(numbers) //모든 숫자를 더하는 함수
string_length(str) //같은 문자열을 넣으면 항상 같은 길이를 줍니다.
--------------------------------------------------------------
데이터: 데이터는 이벤트에 대한 사실을 기록한 것
{ "firstname": "Eric", "lastname": "Normand" } //사람에대한 정보
[1, 10, 2, 45, 3, 98] //숫자 리스트입니다.
코드를 만들 때 위 3가지는 모두 중요하기 때문에 모두 필요합니다. 하지만 액션과 계산, 데이터는 각각 장단점을 가지고 있기 때문에 잘 알고 적절하게 쓰는 것이 좋습니다.
결과적으로 가장 쓰기 좋은 것은 데이터>계산>액션입니다.
한번더 강조해서 함수형 프로그래머는 코드를 액션과 계산, 데이터로 구분합니다. 이것이 함수형 프로그래밍의 핵심 개념입니다.
함수형 프로그래머는 액션과 계산, 데이터를 구분합니다
여러 클라이언트가 작업 완료 표시를 하면 서버에 이메일을 통해 알려주는 서비스를 만든다면 함수형 프로그래머는 이 시나리오에서 동작을 어떻게 구분할까요?
1단계: 사용자가 작업 완료 표시를 함
이것은 UI 이벤트인데 실행 횟수에 의존하기 때문에 액션입니다.
2단계: 클라이언트가 서버로 메시지를 보냄
메시지를 보내는 것도 액션입니다. 메시지 자체는 데이터입니다.
3단계: 서버가 메시지를 받음
메시지를 받는 것은 횟수에 의존하므로 액션입니다.
4단계: 서버가 데이터베이스를 변경
내부 상태를 바꾸는 것은 액션입니다.
5단계: 서버가 누구에게 알림을 보낼지 결정
결정하는 것은 계산입니다. 입력값이 같다면 서버는 항상 같은 결정을 내기 때문입니다.
6단계: 서버가 이메일로 알림을 보냄
이메일 보내기는 액션입니다.
우리 회사의 비회원 페이지를 액션과 계산 데이터를 구분 해본다면?
- 1단계: 사용자가 결제 확인 버튼 까지 다양한 UI/UX를 거침
UI/UX는 실행 횟수에 의존하기 때문에 액션같습니다. - 2단계: 클라이언트가 배차 api를 호출합니다.
api를 호출하니 액션 api의 페이로드는 데이터 - 3단계: 서버가 호출한 api의 파람값을 받고 배차를 할당합니다.
받은 파람값이 같으면 항상 같은 배차를 내리기 때문에 계산입니다. (기사의 스케줄을 변경하는 것은 DB의 내부 상태를 바꾸는 것이니 액션도 포함 되어있겠네요) - 4단계: 서버가 배차 성공을 여부를 클라이언트에게 보냅니다.
성공 여부를 보내는 것은 실행 시점과 보내는 횟수가 다르므로 액션입니다.
액션, 계산, 데이터 특징과 생각해봐야할 것
1. 액션 액션은 실행 시점이나 횟수, 또는 둘 다에 의존합니다. 긴급한 메일을 오늘 보내는 것과 다음 주에 보내는 것은 완전히 다릅니다. 같은 메일을 10번 보내는 것과 한 번 보내는 것 또는 보내지 않는 것 역시 다릅니다. |
- 시간이 지남에 따라 안전하게 상태를 바꿀 수 있는 방법 - 순서를 보장하는 방법 - 액션이 정확히 한 번만 실행되게 보장하는 방법 |
2. 계산 계산은 입력값으로 출력값을 만드는 것입니다. 같은 입력값을 가지고 계산하면 항상 같은 결과값이 나옵니다. 언제, 어디서 계산해도 결과는 같고 외부에 영향을 주지 않습니다. 계산은 테스트하기 쉽고 언제든지 몇 번을 불러도 안전합니다. |
- 정확성을 위한 정적 분석 - 소프트웨어에서 쓸 수 있는 수학적 지식 - 테스트 전략 |
3. 데이터 데이터는 이벤트에 대해 기록한 사실입니다. 데이터는 실행하는 코드만큼 복잡하지 않기 때문에 다른 것과 구분됩니다. 알아보기 쉽고, 데이터 자체로 의미가 있습니다. |
- 효율적으로 접근하기 위해 데이터를 구성하는 방법 - 데이터를 보관하기 위한 기술 - 데이터를 이용해 중요한 것을 발겨하는 원칙 |
액션, 계산, 데이터를 구분하면 어떤 장점이 있나요?
함수형 프로그래밍은 분산 시스템에 잘 어울립니다.
분산 시스템이 어려운 이유
- 메시지 순서가 바뀔 수 있다.
- 메시지는 한 번 이상 도착 할 수도 있고 도착하지 않을 수도 있다.
- 응답을 받지 못하면 무슨일이 생겼는지 알 수 없다.
- 시간에 따라 바뀌는 값을 모델링할 때 동작 방법을 이해하는 것이 중요하지만 쉽지 않습니다.
복잡한 분산시스템의 문제를 다음과 같은 함수형 프로그래밍관점으로 해결 할 수 있습니다.
- 데이터와 계산은 실행 시점이나 횟수에 의존하지 않습니다. 그래서 코드를 데이터와 계산으로 바꿀 수록 분산 시스템에서 생기는 여러 가지 문제를 해결할 수 있습니다.
- 액션은 실행 시점과 횟수에 의존하기 때문에 여전히 문제가 되지만, 코드 전체에 영향을 주지 않도록 격리시키면 됩니다. 또한, 분산 시스템이 아무리 불확실성을 가지고 있다고 해도 액션을 안전하게 다룰 수 있는 기술이 있기 때문에 안심할 수 있습니다.
- 코드의 많은 부분을 액션에서 계산으로 옮기면 결과적으로 액션도 더욱 쉬워집니다.
다른 함수형 프로그래밍 책과 다른 점
- 이 책은 소프트웨어 엔지니어링 관점에서 실용적으로 썼습니다.
- 실제 있을 법한 시나리오로 설명합니다. (피보나치나 합병 정렬 같은 내용은 다루지 않습니다.)
- 소프트웨어 설계를 중심으로 설명합니다.
- 함수형 프로그래밍의 풍부함을 배울 수 있습니다.
- 특정 함수형 프로그래밍 언어에 종속적이지 않습니다.
함수형 사고가 무엇인가요?
함수형 사고는 함수형 프로그래머가 소프트웨어 문제를 해결하기 위해 사용하는 기술과 생각을 말합니다.
함수형 프로그래밍에서 가장 중요하다고 생각하는 두가지 개념
- 액션과 계산, 데이터를 구분해서 생각하는 것
- 파트 1에서는 코드를 구분하는 방법, 액션을 계산으로 리팩터링 하는 방법, 액션을 더 쉽게 다루는 방법을 다룹니다.
- 일급 추상 이라는 개념을 아는 것
- 대부분의 프로그래머는 재사용을 위해 조금 더 일반적인 함수 이름을 짓기 위해 고민합니다. 함수형 프로그래머도 똑같지만 함수에 함수를 넘겨 더 많은 함수를 재사용합니다. 파트 2에서는 일급 추상을 어떻게 쓰고 남용하지 않으려면 어떻게 해야 하는지 설명합니다. 마지막으로 반응형 아키텍처와 어니언 아키텍처를 일급 추상과 연결해서 설명합니다.
이 책을 읽는 기본 규칙
상세내용은 14p 참고
- 특정 언어 기능에 의존하지 않아야 합니다.
- 실용적이라 바로 쓸 수 있어야 합니다.
- 여러분의 현재 가지고 있는 코드와 관계없이 쓸 수 있어야합니다.
💡 QA
Q 저는 객체지향 언어를 쓰는 개발자인데요. 이 책이 도움이 될까요?
A 물론 도움이 됩니다. 어떤 내용은 객체 지향 설계 원칙과 비슷해서 잘 아는 내용도 있을 것이고, 어떤 내용은 새롭다고 생각 할 수 있지만 다른 관점으로 코드를 바라보는데 도움이 됩니다.
Q 왜 자바스크립트로 설명하나요?
A 자바스크립트가 완벽한 함수형 프로그래밍 언어는 아니지만 함수형 프로그래밍에 필요한 모든 것을 가지고 있습니다. 완벽하지 않은 프로그래밍 언어로 함수형 프로그래밍에 필요한 기능을 구현해 보는 것은 가치가 있습니다.
결 론
이 책을 통해 실용적인 함수형 프로그래밍을 배울 수 있습니다. 또 배운 것을 언어와 상황에 관계없이 적용해 볼 수 있습니다.
요점 정리
- 이 책은 두 파트로 나뉘어져 있습니다. 각 파트는 액션과 계산, 데이터를 구분하고 일급 추상을 사용하는 내용을 다룹니다.
- 일반적인 함수형 프로그래밍 정의는 학계 연구자들에게는 도움이 되지만 아직까지는 소프트웨어 공학에 큰 도움이 되지 못한 느낌을 받을 수 있습니다.
- 함수형 사고는 함수형 프로그래밍의 기술과 개념을 의미합니다. 이 책의 주제는 함수형 사고입니다.
- 함수형 프로그래머는 코드를 액션과 계산, 데이터로 나누어서 바라봅니다.
- 액션은 시간에 의존하므로 사용하기 가장 어렵습니다. 액션에서 시간에 의존하는 부분을 분리하면 코드를 더 다루기 쉽게 만들 수 있습니다.
- 계산은 시간에 의존적이지 않습니다. 다루기 쉽기 때문에 가능한 코드를 계산으로 바꾸는 것이 좋습니다.
- 데이터는 정적이고 해석이 필요합니다. 데이터는 저장하거나 이해하기 쉽고 전송하기 편리합니다.
- 이 책의 예제는 대부분의 프로그래머가 익숙한 자바스크립트로 만들어졌습니다. 예제를 이해하기 위해 자바스크립트 기능에 대한 설명이 필요한 경우 설명하겠습니다.
'독서 > 2024' 카테고리의 다른 글
개발자를 넘어 기술 리더로 가는 길 - 타냐 라일리 (1) | 2024.06.15 |
---|---|
[쏙쏙들어오는 함수형 코딩] CHAPTER2 현실에서의 함수형 사고 - 요약 정리 (0) | 2023.08.30 |
[쏙쏙들어오는 함수형 코딩] 들어가기 전 - 요약 정리 (0) | 2023.08.17 |
[구글 엔지니어는 이렇게 일한다: 구글러가 전하는 문화, 프로세스, 도구의 모든것] CHAPTER 15 폐기 - 요약 & 발제문 (0) | 2023.07.30 |
[구글 엔지니어는 이렇게 일한다: 구글러가 전하는 문화, 프로세스, 도구의 모든것] CHAPTER 14 더 큰 테스트 - 요약 & 발제문 (0) | 2023.07.29 |