해당 글은 쏙쏙 들어오는 함수형 코딩 책 내용을 기반으로 작성된 내용입니다.
옮긴 이 머리말
함수형 프로그래밍 언어인 클로저를 사용하면서 좋았던 점
- 불변데이터구조를 사용하면서 변경가능한 상태로 인한 버그가 생기지 않아 좋았습니다.
- 언어에서 제공하는 다양한 함수조합 기능을 사용하기 위해 부수효과가 있는 함수를 분리하자 테스트하기 좋은 코드가 되었습니다.
어떻게 하는 것이 함수형 프로그래밍을 하는 걸까요?
많은 함수형 프로그래밍 자료에서 함수형 프로그래밍은 부수 효과가 없는 순수한 함수로 프로그래밍을 해야 한다고 말합니다. 어떤 자료들은 부수 효과가 전혀 없다고 가정한 상태로 설명하기도 합니다. 하지만 입력도 없고 출력도 없는 소프트웨어는 아무런 의미가 없습니다. 그래서 함수형 프로그래밍을 하려면 부수 효과를 처리하는 방법을 알아야 합니다. 부수 효과를 처리한다는 말은, 없앨 수 있는 부수 효과는 없애고 필요한 부수 효과는 잘 두는 것을 말합니다.
클로저나 스칼라, 하스켈과 같은 함수형 프로그래밍 언어를 사용하면 완전한 함수형 프로그래밍을 보장할 수 있는가?
아닙니다. 이러한 언어들은 불변 데이터 구조를 사용하여 전역변수를 읽고 쓰는 것과 같은 부수 효과가 없지만, 입출력과 같은 부수 효과는 여전히 존재합니다. 따라서 함수형 프로그래밍 언어를 사용하더라도 부수 효과를 다루는 방법을 익혀야 합니다.
이 책이 전달하는 것
- 이 책은 함수형 프로그래머들이 부수 효과를 다루는 방법을 설명하며, 액션과 계산 함수의 분리, 불변 데이터 구조 활용, 부수 효과와 순수 함수 분리 등 다양한 주제를 다룹니다.
- 필요한 부수 효과는 유지하고 불필요한 부수 효과는 최소화하는 방법을 설명합니다.
- 부수 효과가 있는 "액션"과 부수 효과가 없는 "계산" 함수를 잘 분리하고, 불변 데이터 구조를 활용하여 전역 변수와 같은 부수 효과를 없애는 방법을 배울 수 있습니다.
- 입출력과 같은 부수 효과를 순수 함수와 분리하는 방법을 설명하며, 필요한 부수 효과와 그렇지 않은 함수를 설계 시 고려해야 할 점을 강조합니다.
- 동시성 문제에 대한 다양한 측면도 다루며, 여러 작업이 동시에 진행되고 같은 자원을 공유할 때 발생할 수 있는 문제에 대한 해결책을 제시합니다.
- 마지막으로 함수형 프로그래밍과 어울리는 아키텍처에 대한 설명이 포함되어 있으며, 이를 통해 더 나은 소프트웨어를 개발하고자 하는 사람들에게 영감을 줍니다.
추천사
가이 스틸 Guy Steele
52년 넘게 프로그래밍을 해오면서 프로그래밍 스타일에 영향을 많이 끼친 개념은 다음과 같습니다.
- 구조적 프로그래밍의 핵심 개념 두 가지(1970년대 초반)
- goto 문을 몰아내고 흐름 제어를 단순한 패턴으로 만들기 위해 if-then-else, switch 같은 다양한 방법으로 분기하는 구문, for 및 while과 같은 반복문을 실행하는 흐름제어 구조입니다.
- 블록으로 순차적으로 실행되는 코드를 분할하고, 블록 안에서 블록 끝으로 이동하거나 블록 밖으로 나가는 제어 흐름을 가능하게 하는 것입니다. 이 개념은 제어 흐름의 구조를 개선하고 코드의 가독성을 높이는데 중요한 역할을 합니다. 이를 통해 코드의 일관성을 유지하며 블록 안에서의 실행을 제어하고, 필요한 경우 블록 밖으로 이동하여 제어를 조정할 수 있습니다.
//C언어에서 블록 구조를 갖는 예시 코드
#include <stdio.h>
int main() {
int x = 10;
if (x > 5) {
printf("x is greater than 5\n");
} else {
printf("x is not greater than 5\n");
}
return 0;
}
- 객체 지향 프로그래밍의 핵심 개념
객체 지향 프로그래밍은 객체와 클래스, 정보 은닉, 추상 데이터 타입에 대한 초기 개념을 정리했습니다. 생각해 보면 객체지향 프로그래밍의 핵심은 두 가지였는데, 모두 데이터 접근 구조에 관한 내용입니다- ‘캡슐화(encapsulated)’와 '포함(contained)'
- 모든 변수가 어떤 구조에 ‘캡슐화(encapsulated)’되거나 '포함(contained)'되어 코드의 특정 부분에서만 변수에 접근할 수 있기 때문에 코드를 관리하고 읽기 쉬워집니다.
- 프로그램의 가장 위에 변수를 선언하지 않고 블록 안에 로컬 변수를 선언하거나 클래스(또는 모듈)의 메서드(모듈에 있는 프로시저)만 접근할 수 있도록 안전하게 변수를 선언할 수 있었습니다.
- 클래스나 모듈에 있는 변수값이 변경되면 관련된 변수가 함께 변경되도록 메서드 또는 프로시저를 만들기 때문에 변수들의 집합이 일관된 속성을 따르게 할 수 있습니다.
- 상속
- 상속은 단순한 클래스에 변수나 메서드를 추가하거나 메서드를 재정의해서 더 복잡한 객체를 만드는 것을 의미합니다. 상속도 캡슐화가 있기 때문에 가능한 것입니다.
- ‘캡슐화(encapsulated)’와 '포함(contained)'
- 함수형 프로그래밍 핵심 개념
'부수효과(side effect)를 없애라!'라는 슬로건 때문에 너무 단순하게 생각할 수도 있지만, 사실 함수형 프로그래밍은 부수효과 구성(organizing)에 관한 내용입니다. 부수효과를 잘 관리해서 코드의 아무 곳에나 있지 않도록 하는 것입니다. 이 책의 주제이기도 합니다.- 계산과 액션을 구분하는 것
- 계산은 외부에 어떤 영향을 주지 않기 때문에 여러 번 실행해도 항상 같은 결과를 돌려줍니다. 하지만 화면에 글씨를 표시하는 것처럼 액션은 실행할 때마다 다른 결과가 나올 수 있습니다. 이러한 액션은 부수효과를 가지고 있습니다. 코드의 어떤 부분에 부수효과가 있는지와 어떤 부분이 '순수한 계산'인지 쉽게 구분할 수 있는 패턴으로 구성하면 프로그램을 쉽게 이해할 수 있습니다. 이 패턴은 단일 스레드(순차적 실행)에서 실행하는 경우와 다중 스레드(동시 실행)에서 실행하는 경우로 나눌 수 있습니다.
- 배열, 리스트, 데이터베이스와 같은 컬렉션을 하나씩 처리하지 않고 '한 번에' 처리한다는 개념
- '한 번에' 처리하기 위해서는 컬렉션 항목에 외부에 영향을 주는 부수효과가 없어야 합니다. 항목이 독립적일 때 가장 효과적입니다. 이 개념은 첫 번째 개념인 계산과 액션의 구분이 있어야 동작하는 개념입니다.
- 계산과 액션을 구분하는 것
가이 스틸은 1995년 자바 프로그래밍 언어의 첫 번째 스펙을 작성하는데 참여했고, 다음 해에는 자바스크립트 (ECMAScript 표준) 표준을 작성하는데도 도움을 주었습니다. 이 두 언어는 모두 객체지향 언어로 분류됩니다. 자바는 전역 변수 대신 모든 변수를 클래스나 메서드 안에 정의하며, goto 문은 없습니다. 이러한 선택은 구조적 프로그래밍 원칙을 따르기 위한 것으로 여겨집니다. 현재도 많은 개발자들이 goto 문이나 전역 변수 없이 프로그래밍을 잘하고 있습니다.
함수형 프로그래밍은 어떨까요? 대중적인 순수함수형 프로그래밍 언어로는 하스켈이 있습니다. 하스켈로도 화면에 글씨를 표시하거나 로켓을 발사할 수 있지만, 이런 부수효과를 사용하려면 엄격한 원칙을 따라야 합니다. 그중 하나는 코드 중간에 print 문을 사용하여 어떤 일이 일어나는지 확인하는 것을 허용하지 않는 원칙입니다. 순수함수형 언어는 아니지만 자바, 자바스크립트, C++, 파이썬과 같은 언어에서도 함수형 프로그래밍 개념을 적용해 프로그래밍을 더 쉽게 할 수 있습니다. 부수효과를 다루는 원칙을 이해하면 어떤 프로그래밍 언어를 사용하더라도 함수형 프로그래밍의 개념을 활용할 수 있습니다.
머리말
함수형 프로그래밍을 어떻게 정의할 수 있을까?
함수형 프로그래밍 패러다임의 중요한 부분으로 액션과 계산, 데이터를 구분하는 것이지만 이 구분이 패러다임을 정의할 수 있다고 생각하는 사람은 별로 없습니다. 이는 인지 부조화이며 이런 인지 부조화가 사람들이 함수형 프로그래밍을 배울 수 있는 새로운 방법이 될 수 있습니다.
이 책은…
함수형 프로그래밍은 적어도 60년은 되었습니다. 그래서 다뤄야 하지만 여유가 없어 다루지 못한 기술도 많습니다. 하지만 이 책에서 다루는 기술들은 실제 함수형 개발자들이 중요하다고 생각하는 기술이라고 확신합니다.
이 책에 대하여
대상독자
- 2~5년 정도의 경험을 지녔고 최소 하나 이상의 프로그래밍 언어를 알고 있은 개발자
- 책의 예제 코드는 자바스크립트로 작성했지만 C나 C#, C++, 자바 같은 언어를 읽을 수 있다면 문제없습니다.
로드맵
- 1장에서 이 책과 함수형 프로그래밍의 주요 개념을 소개합니다.
- 2장에서 이 책에서 소개하는 기술을 높은 수준으로 살펴봅니다.
파트 1: 액션과 계산, 데이터
- 3장에서 액션과 계산, 데이터를 구분하는 실용적인 기술로 파트 1을 시작합니다.
- 4장에서 코드를 계산으로 리팩터링 하는 방법을 배웁니다.
- 5장에서 계산으로 바꾸지 못하는 액션을 개선하는 방법을 배웁니다.
- 6장에서 카피-온-라이트(copy-on-write)라는 중요한 불변성의 원칙에 대해 배웁니다.
- 7장에서 방어적 복사(defensive copy)라는 또 다른 불변성 원칙에 대해 배웁니다.
- 8장에서 계층이 의미하는 것에 따라 코드를 구성하는 방법을 소개합니다.
- 9장은 유지보수와 테스트, 재사용의 관점에서 계층을 분석하는 방법을 알아봅니다.
파트 2: 일급 추상(first-class abstraction)
- 10장은 일급 값(first-class value)의 개념으로 파트 2를 시작합니다.
- 11장은 함수를 리턴하는 함수가 가진 강력한 힘을 이해합니다.
- 12장은 배열을 반복하는 도구를 만들고 사용하는 방법을 보여줍니다.
- 13장은 12장에서 배운 도구로 복잡한 계산을 만들어봅니다.
- 14장은 재귀를 소개하면서 함수형 도구로 중첩된 데이터를 다루는 방법에 대해 배웁니다.
- 15장은 코드가 어떻게 실행되는지 분석하기 위한 방법으로 타임라인 다이어그램의 개념을 소개합니다.
- 16장은 버그 없이 타임라인 사이에 안전하게 자원을 공유하는 방법에 대해 배웁니다.
- 17장은 버그를 없애기 위해 액션의 순서와 반복을 관리하는 방법을 보여줍니다.
- 18장은 함수형 프로그래밍으로서 서비스를 구축할 수 있는 두 가지 아키텍처에 대한 논의로 파트 2를 마무리합니다.
- 19장은 이 책에 대한 회고와 더 읽을거리를 소개하면서 책을 마칩니다.
읽는 법
- 이 책은 각 장은 다음 장과 연결되어 있어서 처음부터 순서대로 읽는 것이 좋습니다.
- 연습 문제를 꼭 풀어 보세요
- ‘생각해 보기’ 연습 문제는 정답이 없지만 여러분만의 의견을 만들기 위한 연습 문제입니다.
- 다른 연습 문제들은 정답이 있습니다.
- 연습 문제에는 현실적인 상황이 반영되어 있기 때문에 배운 기술을 연마하고 훈련하는 데 도움이 됩니다.
- 언제든지 책 읽기를 멈추세요. 혼자서 책을 읽고 함수형 프로그래밍을 마스터한 사람은 아무도 없습니다. 배운 것이 중요하다고 생각하면 책을 내려놓고 그 기술에 대해 더 깊이 빠져보세요. 여러분이 다시 준비가 되었을 때, 이 책은 항상 거기에 있을 것입니다.
코드 정보
이 책에는 자바스크립트 코드를 사용하지만 함수형 프로그래밍은 반드시 자바스크립트로 해야 한다고 생각하지 않습니다. 사실 자바스크립트는 좋은 함수형 프로그래밍 언어가 아닙니다. 하지만 자바스크립트가 함수형 기능을 많이 가지고 있지 않기 때문에 함수형 프로그래밍을 가르치기 좋은 언어라고 생각합니다. 많은 함수형 개념을 직접 만들어 보면서 함수형 개념들을 깊이 이해할 수 있습니다.
- 텍스트에 한 줄로 표시되는 변수와 기타 구문들은 고정 폭 글꼴을 사용해서 일반 텍스트와 구분했습니다.
- 코드 목록 역시 고정 폭 글꼴을 사용합니다.
- 어떤 코드는 이전 단계와 바뀐 것을 표시하기 위해 강조 표시를 했습니다.
- 최상위의 변수와 함수 이름은 잘 보이게 하기 위해 굵게 표시했습니다.
- 코드에서 주목해서 봐야 할 부분에 밑줄 표시를 했습니다.