[Javascript] 함수형 프로그래밍


함수형 프로그래밍

글에 들어가기 전

먼저 이 글을 읽기 전 생각해봐야 하는게 있습니다.

당신은 광부입니다. 당신이 일하고 있는 광산에서 가장 일을 잘하는 광부이며, 가장 곡괭이를 잘 다루는 광부였습니다. 하지마 어느 날 누군가가 드릴을 가져와, 이 드릴은 곡괭이보다 훨씬 좋다며 굉장히 설득력있는 말을 하며 드릴을 사라고 합니다. 당신은 드릴의 사용법도 잘 모르지만 일단 드릴로 돌을 마구 내리칩니다. 얼마 안있어 당신은 일시적인 유행일 뿐이라며 드릴을 내팽겨치고, 다시 곡괭이를 들어 돌을 내리칩니다. 그때 누군가 나타나서 드릴에 전원을 켜는 방법을 가르쳐 줍니다.

주변에서 아무리 드릴(이 글에선 함수형 프로그래밍)이 좋다고 하지만, 남들이 좋다고 해서 본인이 좋은 게 아닙니다. 즉, 있어보여서 사용하는 거라면 현재 쓰고있는 곡괭이보다 못하다고 생각합니다.

함수형 프로그래밍

함수형 프로그래밍이란, 프로그래밍 패러다임 중 하나입니다. 함수의 응용을 강조하며, 부작용(사이드 이펙트)를 최대한 줄이는 방식입니다.
함수의 부작용을 제거한다면, 프로그램의 동작을 이해하고 예측하기 쉬워집니다.
만약 당신이 현재의 상태에 의존하는 함수를 만들었다면, 함수 그 자체만을 보고 어떤 결과가 나올지 예측하기란 쉽지 않은 일일 것 입니다. 하지만 함수에 입력되는 인수(인자)에 의존하는 함수를 만든다면, 예측이 훨씬 쉬워집니다. 이것이 함수형 프로그래밍을 하는 이유이자, 동기입니다.

자바스크립트 속 함수형 프로그래밍

사실 자바스크립트는 함수형 프로그래밍이 아닌, 객체지향 프로그래밍이라고 할 수 있습니다. MDN 공식 문서에서도 그에 대해 말 하고 있습니다.
하지만 자바스크립트와 같이 문법이 유연할 수록, 함수형 프로그래밍에 더욱 힘을 실어줘야 한다고 생각합니다.

순수함수

순수함수란, 부작용(사이드 이펙트)이 없는 함수를 얘기합니다. 부작용이 없는 함수란, 함수가 실행이 되어도 함수 밖에 있는 상태는 변하지 않는다는 걸 말합니다.

var v = 1;

// 함수 실행시 인자만을 이용하는 함수.
function pureFunction(x) {
  return x * x;
}

// 함수 실행시 외부의 상태가 변하는 함수.
function sideEffectFunction(x) {
  v = x;
  return x * x;
}

console.log(v); // 1
console.log(pureFunction(3)); // 9
console.log(sideEffectFunction(3)); // 9
console.log(v); // 3

부작용이 있는 함수 호출시 함수 외부의 상태가 변한다.

부작용이 있는 함수가 실행되면, 외부의 상태를 알기가 쉽지 않습니다. 또한, 상태가 변한다면 원래 되던 동작들이 작동하지 않을 가능성이 있습니다. 그렇기 때문에 우리는 순수함수를 작성해야 합니다.

고계함수

고계함수란, 함수를 다루는 함수를 뜻합니다. 함수형 프로그래밍에서는 함수 또한 값(1과 같은)이 될 수 있기 때문에, 함수의 인자에 함수를 넘겨줘서 함수를 다룰 수 있습니다. 마찬가지로 함수를 반환해줄 수 있습니다.
자바스크립트에는 몇가지 고계함수들이 존재합니다. 예를 들어 Array 프로토타입에 있는 map, filter, reduce와 같은 것들이죠.

var fruits = ['apple', 'banana', 'melon'];

for (var i = 0, string = ''; i < fruits.length; i++) {
  string += fruits[i]+' ';
}

var string2 = fruits.reduce(function(acc, string) {
  return acc+' '+string;
}, '');

console.log(string); // apple banana melon 
console.log(string2); // apple banana melon

고계함수인 reduce와 선언형 프로그래밍의 for을 사용한 코드.

불변성

함수형 프로그래밍에서는, 가변 데이터(변하는 데이터)를 멀리합니다. 그래서 함수형 프로그래밍은 불변성(변하지 않는)에 가깝다고 볼 수 있습니다. 가변 데이터를 멀리하는 이유 또한, 데이터가 변하면 생길 수 있는 부작용(사이드 이펙트)를 없애기 위해서입니다.
만약, 데이터를 변해야 하는 상황이 온다면, 데이터를 복사하고, 또 다른 데이터를 만들어야만 합니다.

var obj = {
  value: 1
}

// 기존에 있던 객체를 변화시켜 불변성에 어긋납니다.
function changeObj(value) {
  obj.value = value;
  return obj;
}

// 새로운 객체를 리턴합니다.
function newObj(value) {
  return Object.assign({}, obj, { value: value }); // 객체를 복사하는 메서드
}

changeObj(3); // { value: 3 }
newObj(2); // { value: 2 }

객체의 상태를 변화시키는 함수와 객체를 새로이 만들어내는 함수.

정리

자바스크립트는 객체지향 언어이기 때문에, 완벽히 함수형 프로그래밍을 할 수 없습니다. 하지만 가능한 범위내에서 함수형 프로그래밍 법칙을 지킨다면, 코드를 더 예측하기 쉬워질 것입니다.
또한 기존의 객체지향으로 코딩하는 것에서 벗어나, 함수형으로 코딩을 한다면 사고의 범위 또한 늘어날 것입니다. 그에 대한 좋은 책이 있어 소개드립니다 [함수형 사고]

끝으로

원래.. 수요일에 쓰기로 했는데 뭘 써야할지 주제가 생각이 안나서 결국 금요일에 썼당… 암튼 글 자체에는 크게 불만은 없는 것 같은데. 뭔가를 표현하는 게 아직 많이 부족한 것 같다. 아무래도 글을 더 많이 써봐야 나아지지 않을까..




© 2019. by jong-hui

Powered by aiden