왜 함수형 프로그래밍인가?

devdo·2022년 1월 8일
0

함수형 프로그래밍은 익히 들어봤지만 뭐라고 얘기해보면 잘 말할 수가 없었다. 이번 기회에 정리해보자.

국내 기술면접 가이드 라는 곳에서 함수형 프로그래밍 방식을 정리한 글을 가져와 봤다.

국내 기술면접 가이드

거기서 3가지를 정리해보면,

1) immutable data(불변데이터)
2) first class citizen(1급 객체)
3) Reactive Programming(선언적 프로그래밍)

immutable

우선 immutable과 mutable의 차이에 대해서 이해를 하고 있어야 한다. immutable이란 말 그대로 변경 불가능함을 의미한다. immutable 객체는 객체가 가지고 있는 값을 변경할 수 없는 객체를 의미하여 값이 변경될 경우, 새로운 객체를 생성하고 변경된 값을 주입하여 반환해야 한다. 이와는 달리, mutable 객체는 해당 객체의 값이 변경될 경우 값을 변경한다.

함수형 프로그래밍을 사용해야되는 이유 중 하나가 바로 immutable data이다. 한번 정해진 값은 바뀌지 않는다는 것.

primitive type 뿐만 아니라 Java의 Collection에 해당하는 자료 구조들에도 똑같이 적용된다.

처리할 데이터가 불변이기 때문에 우리는 수학적 의미의 순수 함수(pure function) 형태로 함수를 만들게 된다.

대표적인 String객체는 Java에서도 대표적인 불변 객체다. 문자열을 다루는 함수들만큼은 좀더 ‘함수형' 스타일에 맞게 짜야 한다.

first-class citizen

함수형 프로그래밍 패러다임을 따르고 있는 언어에서의 함수(function)는 1급 객체(first class citizen)로 간주된다. 1급 객체라 함은 다음과 같은 전제조건이 있다.

  • 변수나 데이터 구조안에 넣을 수 있다.
  • 파라미터로 전달 할 수 있다.
  • 동적으로 프로퍼티 할당이 가능.
  • 리턴값으로 사용할 수 있다.

이해하기 쉬운 예제로 확인하고자 하면 이 링크Javascript에서 왜 함수가 1급 객체일까요?에서 보시길 바란다.

자바스크립트의 경우 함수가 1급 객체가 되는 것이며 자바의 경우 함수형 인터페이스(추상메서드가 하나인 인터페이스)를 통해 구현이 가능하다.

자바스크립트 함수는 1급 객체?

Javascript에서 함수를 반환할 수 있을 뿐만 아니라 함수를 받을 수 있는 함수를 만들수 있으니 함수형 프로그래밍으로 Javascript에서 많이 볼 수 있다. 하나 이상의 함수를 인수로 받거나 함수를 반환하는 고차 함수를 만들 수도 있는 것이다.

함수형 인터페이스이란?

하나의 추상 메서드만 가지는 인터페이스를 말한다.
함수형 인터페이스여야만 람다 표현식을 쓸 수 있다.

// 함수형 인터페이스 샘플
interface MyInterface {
	void printMsg();
}

참고)
함수형 인터페이스에 @FunctionalInterface 애너테이션을 사용할 수 있다. 굳이 애너테이션이 아니더라도 추상 메서드가 하나인 인터페이스는 함수형 인터페이스로 처리된다. 다만 애너테이션을 사용할 경우 코드상에 명시되어 확인이 쉽고, 컴파일러가 단일 추상 메서드만을 가지고 있는지 검사하기 때문에 혹시 모를 구현상의 오류를 방지해 주는 것이다.


Reactive Programming

반응형 프로그래밍(Reactive Programming)은 선언형 프로그래밍(declarative programming)이라고도 불리며, 명령형 프로그래밍(imperative programming)의 반대말이다.

명령형(Imperative) vs 선언형(Declarative)

  • 명령형 프로그래밍
    원하는 결과를 얻기 위해 특정 단계를 설명하는 코드 라인을 사용. -> for, if 에 따른 로직과 특정기능의 메서드 호출(명령)하는 형식.

  • 선언적 프로그래밍
    흐름 제어를 추상화하고 데이터 흐름을 설명하는 코드 라인을 사용. -> 데이터가 입력으로 주어지고 데이터를 다루는 과정(흐름)을 정의하는 형식.

선언형 프로그래밍함수형 프로그래밍 패러다임을 활용하는 것을 말한다. 자바에서는 반응형 프로그래밍으로스트림(stream)으로 구현했다.

스트림이란 값들의 집합으로 볼 수 있으며 제공되는 함수형 메소드를 통해 데이터를 immutable(불변)하게 관리할 수 있다.

함수형 프로그래밍 조건

일반적으로 함수형 프로그래밍에서는 다음 세가지 조건을 만족시켜야 한다.

1) 순수 함수(pure function)
2) 고차 함수(High Order Function)
3) 익명 함수(Anonymous function)

순수 함수(pure function)

순수 함수란 같은 입력에 대해 항상 같은 출력을 반환하는 함수로 다음과 같은 조건을 만족하는 함수를 말한다. 멀티쓰레드에서도 안전하고(Thread safe) 병렬처리 및 계산도 가능하다.

  • 동일한 입력에 대해 항상 같은 값을 반환.
  • 부작용(다른 요인에 따른 결과변경)이 없는 결과를 생성. -> 함수에서 인자를 변경하거나 프로그램의 상태를 변경하지 않음.

고차함수(High Order Function)

1급 함수의 서브셋으로 다음 조건을 만족하는 함수를 말한다.

  • 함수의 인자로 함수를 전달할 수 있다.
  • 함수의 리턴값으로 함수를 사용할 수 있다.

익명 함수(Anonymous function)

이름이 없는 함수를 말하며 람다식으로 표현되는 함수 구현을 말한다.

합성 함수(function composition)는 새로운 함수를 만들거나 계산하기 위해 둘 이상의 함수를 조합하는 것을 말하는 것으로 데이터가 흐르도록 일련의 파이프라인을 형성하는 개념 이다.

함수형 프로그램은 작은 단위의 순수 함수들로 구성되어 있기 때문에 이 함수들을 연속적 혹은 병렬로 호출해서 더 큰 함수를 만드는 과정으로 프로그램이 구성된다.

실제 구현상에는 메서드 체이닝 방식으로 함수들을 연결해 사용하는 형태로 나타난다.

왜 다시 함수형 프로그래밍인가?

사실, 함수형 프로그래밍 방식은 예전에(1930년대까지 내려간다...) 나온 방식이다. 그런데 갑자기 현제에 와서 각광받는 이유가 무엇일까?

멀티코어가 기본이 되면서 ‘동시성' 처리에 함수형 프로그래밍이 강점을 보이기 때문이 아닐까 싶다.

멀티 쓰레드 프로그래밍이 불과 몇년전까지도 가능한 피해야 할 문제였다면 이제는 반드시 고려해야 하는 기본이 되었다. 그러나 아직 보통의 많은 개발자들은 어려워한다.

Side effect
반환 값 이외에, 호출 된 함수 밖에서 관찰할 수 있는 어플리케이션의 상태 변경되는 현상

Side effect에 기반한 객체지향 프로그래밍에서는 멀티쓰레딩에 효과적으로 대응하기 쉽지 않지만,

불변 값을 주로 다루는 함수형 프로그래밍은 본질적으로 동시성 처리가 쉬워지기 때문에 Side effect를 피할 수 있어 소프트웨어의 확장, 리팩토링, 디버그, 테스트 그리고 유지를 훨씬 간단하게 할 수 있는 것이다.


정리

함수형 프로그래밍의 특징

  1. Side effect가 없다.
    순수함수의 조합으로 이루어지기 때문에 결과값은 변하지 않는다.
  2. 간결하다.
    함수형 프로그래밍의 중요 개념인 순수함수, 불변성, 1급 객체, 선언적 프로그래밍과 같은 기능으로 간결하고 일련의 함수 구성(Composition)을 가능하게 해준다.
  3. 상태(State)가 없다.
    함수형 프로그래밍은 상태(State)를 배제(공유 없음)하여 Side Effect가 없게 동작한다(Thread safe). 그러나 프론트에서 상호작용(Interaction)은 대부분 상태 변화로 모델링된다.


참고

https://dinfree.com/lecture/language/112_java_9.html
https://github.com/JaeYeopHan/Interview_Question_for_Beginner/tree/master/Development_common_sense#%ED%95%A8%EC%88%98%ED%98%95-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D
https://medium.com/@jooyunghan/%ED%95%A8%EC%88%98%ED%98%95-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D-%EC%86%8C%EA%B0%9C-5998a3d66377

profile
배운 것을 기록합니다.

0개의 댓글