순수 함수(Pure Function)와 부수효과(Side Effect)
순수 함수(Pure Function)는 입력값이 있고 인자가 주어지면 늘 같은 출력값을 내놓는 함수이다. 이 과정에서 어떠한 부수효과(Side Effect)도 트리거 하지 않는다. 즉 함수 외부에선 아무것도 바꾸지 않는다는걸 의미한다.
function add(num1, num2) {
return num1 + num2;
}
console.log(add(2, 5));
예시를 들어보면 add 함수는 같은 값(2,5)을 입력하면 늘 같은 값(7)을 출력한다. 이는 가장 완벽한 순수함수의 예시이다.
function addRandom(num1) {
return num1 + Math.random();
}
console.log(addRandom(2));
그럼 이번엔 비순수 함수의 예시를 들어보자 addRandom함수는 같은 값(2)를 입력해도 매번 실행될때마다 다른 값을 반환한다. Math.random()이라는 무작위 함수를 추가했기 때문이다.
이외에도 함수에 부수효과가 있는 경우에도 비순수 함수라고 한다.
부수효과(Side Effect)란 함수의 외부를 바꿔놓는것을 일컫는 용어이다.
사이드 이펙트의 예시로는
파일 입출력, 네트워크 요청, 데이터베이스 작업, DOM 조작, 시간 지연, 상태 변경 등일수도 있고, 단순히 함수 밖의 정의되어 계속 변하는 변수같이 사소한것 일수도 있다. 부수효과는 프로그래밍에서 예측할 수 없는 동작을 일으킬 수 있으며 이는 테스트를 작성하기 어렵게 만든다. 또한 코드의 가독성과 유지보수성을 저하시킬 수 있다.
let a = 0;
function add(num1,num2) {
const sum = num1 + num2;
a = sum; // Side Effect
return sum;
}
예를들면 이 함수는 비순수 함수인데, a = sum 줄에서 함수 밖에서 정의된 변수를 바꾸는 부수효과를 발생시키기 때문이다.
또다른 예로는 함수에 들어가는 객체나 배열을 바꾸는게 있다.
const drinks = ['water','juice','tea']
function printDrinks(drinks){
drinks.push('alcohol'); // Side Effect
console.log(drinks)
이 함수를 실행하면 기존 drinks 배열에 'alcohol' 이라는 요소가 추가되어 출력된다. array.push()라는 메소드는 원본 배열을 변경시키는 부수효과를 가지고 있기 때문에 printDrinks 함수는 비순수 함수이다.
그렇다면 비순수 함수는 무조건 지양해야 할까??
애플리케이션을 구축할때 부수효과를 피하는것은 불가피하다. 하지만 비순수 하거나 부수효과를 갖는 함수의 양을 줄이도록 노력 해야한다. 가능하면 순수 함수를 사용하여 프로그램을 작성하는게 좋으며, 이렇게 함으로써 코드의 가독성과 유지보수성이 향상되며, 버그를 줄일 수 있다.
추가적으로 비순수 함수를 사용할때는 함수이름을 지을때 이 함수가 부수효과를 낸다는것을 명확하게 표현하면 좋다.