[Java] 함수형 프로그래밍이란?

nathan·2022년 1월 23일
0

JAVA

목록 보기
24/45

프로그래밍 패러다임(Programming Paradigm)

  • 프로그래밍 패러다임은 프로그래머에게 프로그래밍의 관점을 갖게 해 주고, 결정하는 역할을 한다.
  • 예를 들어 OOP는 프로그래머들이 프로그램을 상호작용하는 객체들의 집합으로 볼 수 있게 하는 반면에, 함수형 프로그래밍(FP)은 상태값을 지니지 않는 함수값들의 연속으로 생각할 수 있게 해준다.
  • 소프트웨어 공학의 서로 다른 무리가 서로 다른 방법론을 지원하듯, 서로 다른 프로그래밍 언어는 서로 다른 프로그래밍 패러다임을 지원한다.
  • 어떠한 언어는 특정한 하나의 패러다임을 지원하기도 하는데, jdk 1.8 이전의 Java나 smalltalk가 객체지향 프로그래밍을 지원했다면, R, 하스켈 등은 함수형 프로그래밍을 지원한다.
  • 자바 또한 jdk 1.8부터 함수형 프로그래밍 패러다임을 지원하기 위해, 람다식, 생성자 레퍼런스, 메서드 레퍼런스를 도입했고, 선언형 프로그래밍의 장려를 위해 Stream과 같은 표준 API 등도 추가했다.

함수형 프로그래밍(FP)이란?

  • 객체지향 프로그래밍(OOP)와 같은 프로그램 패러다임 중 하나
  • 객체지향 프로그래밍은 객체 간 메시지와 협력 관계의 정의로 이루진 프로그래밍 패러다임이라면, 함수형 프로그래밍은 단순 함수의 조합으로 이루어진다.
  • 해당 함수들은 외부와의 관계가 없이 단지 함수 자신만으로 존재한다.
  • 함수가 1등 시민(first-class citizen)으로, 함수를 타입으로 지정하거나, 인자 값으로 넘기거나, 리턴 값으로 받을 수 있다.(마치 함수도 객체처럼 변수, 함수의 인자, 리터럴하게 다룰 수 있음을 의미)
  • 함수형 프로그래밍은 객체지향 프로그래밍보다 높은 수준의 추상화를 요구한다.

함수형 프로그래밍의 핵심 요소 4가지

(1) Pure Function

  • 동일한 입력 값에 대하여 항상 같은 값을 반환하는 함수를 의미한다.
  • 전역 변수를 사용하거나, 변경을 하는 것을 막아 side effect의 발생을 최소화 시킨다.
private String name = "nathan";

// Not Pure
public String Hello(){
   return "Hello" + name;
}


// Pure
public static String Hello(String name){
   return "Hello" + name;
}

(2) Not foreach (= No Iterate)

  • for, while 문과 같은 반복문을 사용하지 않는다.
  • 함수형에서는 반복문 대신 map, filter와 같은 함수를 매개변수로 받는 메서드를 이용한다.
List<Integer> numbers = List.of(1, 2, 3, 4, 5);
// for loop
for (int i = 0; i < numbers.size(); i++){
   System.out.println(numbers.get(i));
}

// functional
numbers.forEach((num) -> {
   System.out.println(num);
});

(3) High Order Function

  • 고차함수라고도 부르며, 함수를 인자로 받거나 함수를 반환 값으로 이용할 수 있는 것을 말한다.
  • 함수를 더 추상화하면 차원이 높아지는 고차함수로 표현할 수 있다.
  • 그 중에서도 여러 값이 들어있는 콜렉션을 탐색하고, 비교하고, 찾아서 정리하는 기능은 자주 사용한다.
  • 클로져(Closure) : 내부 함수가 외부 함수의 맥락(context)에 접근할 수 있는 것을 뜻함.
    • 외부 함수 안에 있는 내부 함수가 외부 함수의 지역 변수를 사용할 수 있다라는 뜻
    • 특이한 점 : 외부 함수가 종료되더라도 내부 함수에서 참조하는 외부 함수의 context는 유지됨.
    • 클로져가 생성되는 시점에 함수 자체가 복사되어 따로 context를 유지하기 때문.
    • ++ 익명 클래스에 context를 념겨주는 것이 바로 클로져(Closure)
Function<String, Function<String, String>> hello = (helloText)  -> {
   return (name) -> {
      return helloText + " " + name;
   };
};

Function<String, String> hello1 = hello.apply("Hello");
Function<String, String> hello2 = hello.apply("HI");

System.out.println(hello1.apply("nathan"));
System.out.println(hello2.apply("nathan"));

>>>
Hello nathan
HI nathan

(4) Immutability

  • 불변성은 변할 수 없는 값을 의미한다.
  • 자바에서 final 변수를 선언해서 불변값을 만들 수 있지만, 참조값을 final로 선언하는 경우에는 값이 변할수도 있다.
final String name = "nathan";
name = "Nathan"; // compile error

final List<String> tmpList = Arrays.asList("a", "b", "c");

// but change value
tmpList.add("d");
  • 자바의 경우 Collection 객체들은 아래와 같은 방법으로 불변성 객체 생성이 가능하다. (
final List<String> tmpList = Collections.unmodifiableList(Arrays.asList("a", "b", "c"));
tmpList.add("d"); // error

왜 함수형 프로그래밍을 하는가? (개인 생각)

  • 빅데이터 시대가 도래하게 되면서, 데이터 핸들링의 중요성이 더욱 대두되었다.
  • 데이터가 변하지 않으면서, 의도된 대로 안전하게 가공하는 것이 목표가 되었고, 순수함수, 불변성 등을 특징으로 하는 함수형 프로그래밍이 각광받게 되었다.
  • 함수형 프로그래밍은 전역 상태를 허용하지 않기 때문에 병렬 프로세스나 쓰레드에 안전하다.
  • 또한 추상화 레벨이 높아, 필요한 정보만 보여주기 때문에, 전체적인 흐름을 파악하는 데에도 도움이 된다.

Reference

profile
나는 날마다 모든 면에서 점점 더 나아지고 있다.

0개의 댓글