함수형 프로그래밍에 대해서 설명해주세요.

백엔드와 관련된 질문이에요.

함수형 프로그래밍(Functional Programming) 은 객체지향 패러다임과 마찬가지로 하나의 프로그래밍 패러다임입니다. 객체지향 프로그래밍은 움직이는 부분을 캡슐화하여 코드의 이해를 도우며, 함수형 프로그래밍은 움직이는 부분을 최소화하여 코드 이해를 돕습니다. 이 둘은 상충하는 개념이 아니며, 함께 조화되어 사용될 수 있습니다. 함수를 합성하여 복잡한 프로그램을 쉽게 만들고, 부수 효과를 공통적인 방법으로 추상화하는 것이 함수형 프로그래밍의 핵심 개념입니다.

부수 효과(Side Effect) 는 값을 반환하는 것 이외에 부수적으로 발생하는 일들을 의미해요. 변수를 수정하거나, I/O 작업 등이 해당됩니다. 사람이 한 번에 인지할 수 있는 작업은 한정되어 있습니다. 부수 효과가 많은 코드는 이해하고 결과를 예측하기 어려울 수 있습니다. 함수형 프로그래밍은 부수 효과를 추상화하고 분리하여 코드를 이해하기 쉽게 만들 수 있습니다.

함수를 합성한다는 게 무슨 의미인지 궁금해요. 🤔

특정 함수의 공역이 다른 함수의 정의역과 일치하는 경우, 두 함수를 이어서 새로운 함수를 만드는 연산을 함수 합성(Function Composition) 이라고 해요. 프로그래밍에서 공역과 정의역은 타입에 해당됩니다. 쉽게 말씀드리자면, A 함수에서 int 타입을 반환하고, B 함수에서 int 타입을 인자로 받는다면, B(A())와 같은 형태로 호출하는 것을 함수 합성이라고 합니다.

함수형 프로그래밍은 함수를 합성하여 복잡한 프로그램을 쉽게 만듭니다. 함수는 입력이 들어오면 부수 효과의 발생과 함께 결과를 반환할 수 있습니다. 하지만, 부수 효과가 존재하는 함수는 합성하기가 까다롭습니다.

// 부수효과가 존재하는 sum 함수는 다른 함수와 합성하기 까다로울 수 있다.
//     1. 다른 함수에서 1부터 1,000까지 더하는 함수가 필요하다면?
//     2. 다른 함수에서 1부터 100까지 곱하는 함수가 필요하다면?
int sum() {
    int sum = 0;
    for(int i = 1; i <= 100; i++) {
        sum += i;
    }

    return sum;
}

순수 함수(Pure Function) 은 같은 입력이 들어오면, 항상 같은 값을 반환하는 함수를 의미하는데요. 순수 함수는 부수효과를 일으키지 않습니다. 함수형 프로그래밍에서 함수 합성은 순수 함수로 이뤄집니다.

class FunctionCompositionTest {

    @Test
    @DisplayName("함수 합성")
    void fp() {
        System.out.println(sum()); 
        System.out.println(factorial(10));
    }

    // 1부터 100까지의 합
    private int sum() {
        return loop((a, b) -> a + b, 0, range(1, 100));
    }

    // 팩토리얼
    private int factorial(int n) {
        return loop((a, b) -> a * b, 1, range(1, n));
    }

    private int loop(BiFunction<Integer, Integer, Integer> fn, int sum, Queue<Integer> queue) {
        if (queue.isEmpty()) {
            return sum;
        }

        return loop(fn, fn.apply(sum, queue.poll()), queue);
    }

    private Queue<Integer> range(Integer start, Integer to) {
        return IntStream.rangeClosed(start, to)
                .boxed()
                .collect(Collectors.toCollection(LinkedList::new));
    }
}

추가 학습 자료를 공유합니다.