함수형 프로그래밍

fe_sw·2022년 8월 6일
0

Programming

목록 보기
2/3

함수형 프로그래밍

명령형 프로그래밍을 기반으로 개발했던 개발자들은 개발하는 소프트웨어의 크기가 커짐에 따라, 복잡하게 엉켜있는 스파게티 코드를 유지보수하는 것이 매우 힘들다는 것을 깨닫게 되었다.

이를 해결하기 위해 함수형 프로그래밍이라는 프로그래밍 패러다임에 관심을 갖게 되었다. 함수형 프로그래밍은 거의 모든 것을 순수 함수로 나누어 문제를 해결하는 기법으로, 작은 문제를 해결하기 위한 함수를 작성하여 가독성을 높이고 유지보수를 용이하게 해준다.

명령형 프로그래밍에서는 메소드를 호출하면 상황에 따라 내부의 값이 바뀔 수 있다. 즉, 우리가 개발한 함수 내에서 선언된 변수의 메모리에 할당된 값이 바뀌는 등의 변화가 발생할 수 있다.

하지만 함수형 프로그래밍에서는 대입문이 없기 때문에 메모리에 한 번 할당된 값은 새로운 값으로 변할 수 없다.

함수형 프로그래밍은 순수함수와 보조 함수의 조합을 통해 로직내에 존재하는 조건문과 반복문을 제거하여 복잡성을 해결하고,변수의 사용을 억제하여 상태변경을 피하려는 프로그래밍이다.

부수 효과가 없는 순수 함수를 1급 객체로 간주하여 파라미터나 반환값으로 사용할 수 있으며, 참조 투명성을 지킬 수 있다.

부수효과

  • 변수의 값이 변경됨
  • 자료 구조를 제자리에서 수정함
  • 객체의 필드값을 설정함
  • 예외나 오류가 발생하며 실행이 중단됨
  • 콘솔 또는 파일 I/O가 발생함

순수함수

순수함수는 같은 입력이 주어지면, 같은 출력을 반환해야하고, side effect(부작용)이 없어야한다.

부수 효과(Side Effect)들을 제거한 함수들을 순수 함수(Pure Function)이라고 부르며, 함수형 프로그래밍에서 사용하는 함수는 이러한 순수 함수들이다

  • 동일한 입력에는 항상 같은 값을 반환해야 하는 함수
  • 함수의 실행이 프로그램의 실행에 영향을 미치지 않아야 하는 함수
  • 함수 내부에서 프로그램 상태를 변경하는 Side Effect가 없는 것

let num = 1;

function add(a) {
    return a + num;
}

add라는 함수 안에서 전역으로 선언된 변수인 num을 참조하기 때문에 순수함수라고 볼 수 없다.


// 순수함수
function add(a, b) {
    return a + b;
}

const result = add(2, 3);

위와 같이 add의 함수가 프로그램 실행에 영향을 미치지 않고 입력 값에 대해서만 값의 변환이 있으므로 순수함수이

비상태, 불변성

  • 함수형 프로그래밍에서의 데이터는 변하지 않는 불변성을 유지해야 한다.
  • 데이터의 변경이 필요한 경우, 원본 데이터 구조를 변경하지 않고 그 데이터의 복사본을 만들어서 그 일부를 변경하고, 변경한 복사본을 사용해 작업을 진행한다.

let person = { name: "jongmin", age: "26" };

function increaseAge(person) {
    person.age = person.age + 1;
    return person;
}

increaseAge 함수에서 전역으로 선언된 person의 age 속성을 변경하므로 불변성 유지를 만족하지 못한다.


// 비상태, 불변성 만족
const person = { name: "jongmin", age: "26" };

function increaseAge(person) {
    return { ...person, age: person.age + 1 };
}

전역으로 선언된 person 객체를 직접 변경하지 않고, 데이터의 복사본을 만들어, 그 복사본을 사용해 작업을 진행하고 반환한다.

선언형 함수


let numbers = [1, 2, 3];

function multiply(numbers, multiplier) {
    for (let i = 0; i < numbers.length; i++) {
        numbers[i] = numbes[i] * multiplier;
    }
}

for문을 사용해서 배열의 각 요소에 multiplier 곱해주는 명령형 프로그래밍이다.

함수형 프로그래밍에서는 마찬가지로 if,switch,for 등 명령문을 사용하지 않고 함수형 코드로 사용해야한다.


// 선언형 프로그래밍
function multiply(number, multiplier) {
    return number.map((num) => num * multiplier);
}

위의 예시는 for문을 map으로 대치했고, Javascript 에서는 filter,map,take,reduce 등의 고차함수를 사용한다.

일급객체

함수형 프로그래밍에서는 함수가 1급 객체가 된다. 1급 객체의 특징은 다음과 같다.

  • 변수(variable)에 담을 수 있다.
  • 다른 함수를 인자(argument)로 받는다.
  • 다른 함수의 결과로 리턴 될 수 있다.
  • 할당에 사용된 이름과 관계없이 고유한 구별이 가능하다.
  • 동적으로 프로퍼티 할당이 가능하다.

참고: https://velog.io/@fe_jungseok/%EA%B3%A0%EC%B0%A8%ED%95%A8%EC%88%98

장단점

장점

  • 높은 수준의 추상화를 제공한다.
  • 함수 단위의 코드 재사용이 수월하다.
  • 불변성을 지향하기 때문에 프로그램의 동작을 예측하기 쉬워진다.

단점

  • 순수함수를 구현하기 위해서는 코드의 가독성이 좋지 않을 수 있다.
  • 함수형 프로그래밍에서는 반복이 for문이 아닌 재귀를 통해 이루어지는데 (deep copy), 재귀적 코드 스타일은 무한 루프에 빠질 수 있다.
  • 순수함수를 사용하는 것은 쉬울 수 있지만 조합하는 것은 쉽지 않다.

참고

0개의 댓글