Functional Programming(FP)

업데이트:

Functional Programming(OOP)

  • 자료 처리를 수학적 함수의 계산으로 취급하고 상태와 가변 데이터를 멀리하는 프로그래밍 패러다임의 하나이다.1

특징

Immutability

  • 함수형 프로그램의 핵심 개념으로, 객체를 생성한 후 수정할 수 없는 객체이다.
  • Java에서는 Final keyword를 사용하고 Setter method를 사용하지 않음으로써 불변 Object 생성2할 수 있으나, Reflection을 통해 깨버릴 수 있다.
public class Musician {

  private final String name;

  public Musician(String name) {
    this.name = name;
  }

  public String getName() {
    return this.name;
  }

}
public class Main {

  public static void main(String[] args) throws Exception {
    Musician musician = new Musician("George Winston");
    System.out.println(musician.getName());

    // Using reflection.
    Field name = musician.getClass().getDeclaredField("name");
    name.setAccessible(true);
    name.set(musician, "Steve Barakatt");

    // Change name.
    System.out.println(musician.getName());
  }

}
George Winston
Steve Barakatt

First-class

  • 함수를 매개변수로 전달할 수 있다.
public class PassingAFunctionToAnotherFunction {

  public static void main(String[] args) {
    IntStream.range(1, 6).boxed().collect(Collectors.toList()).sort((x, y) -> y - x);
  }

}
  • 함수를 결과로 반환할 수 있다.
public class ReturningFunctionsFromFunctions {

  public static void main(String[] args) {
    IntStream.range(1, 6).boxed().collect(Collectors.toList()).sort(getSort());
  }

  // Returns the function as a result.
  private static Comparator<Integer> getSort() {
    return (x, y) -> y - x;
  }

}
  • 변수에 함수를 할당할 수 있다.
public class StoringFunctionsInVariables {

  public static void main(String[] args) {
    Comparator<Integer> comparator = (x, y) -> y - x;
    IntStream.range(1, 6).boxed().collect(Collectors.toList()).sort(comparator);
  }

}

Lazy evaluation

불필요한 연산을 피하기 위해서 값이 실제로 쓰이기 전까지 그 값의 계산을 최대한 미루는 것이다.

public class LazyEvaluation {

  public static void main(String[] args) {
    List<Integer> numbers = IntStream.range(1, 31)
        .filter(num -> {
          System.out.println(num + " % 2 : " + num % 2);
          return num % 2 == 0;  
        })
        .filter(num -> {
          System.out.println(num + " % 3 : " + num % 3);
          return num % 3 == 0;
        })
        .map(num -> {
          System.out.println(num + " / 6 : " + num / 6);
          return num / 6;
        })
        .boxed()
        .collect(Collectors.toList());

    System.out.println(numbers);
  }

}
1 % 2 : 1
2 % 2 : 0
2 % 3 : 2
3 % 2 : 1
4 % 2 : 0
4 % 3 : 1
5 % 2 : 1
6 % 2 : 0
6 % 3 : 0
6 / 6 : 1
7 % 2 : 1
...

종류

Anonymous Function

  • 이름이 없는 함수이다.
  • Java에서는 Lambda가 이에 해당한다.

Pure Function

  • 부작용(Side Effect)과 외부에 영향이 없는 함수이다.
  • 내부에 상태를 갖지 않아, 같은 입력에 대해서는 항상 같은 출력이 보장된다.
public class PureFunction {

  public static void main(String[] args) throws InterruptedException {
    for (int count = 0; count < 5; count++) {
      System.out.println(nonPureFunction());
      System.out.println(pureFunction(1000, 5));
      Thread.sleep(1000L);
    }

  }

  private static LocalDateTime nonPureFunction() {
    return LocalDateTime.now();
  }

  private static int pureFunction(int price, int num) {
    return price * num;
  }

}

High-Order Function

  • 매개변수로 전달된 함수를 이용하여 만든 새로운 함수이다.
public class HighOrderFunction {

  public static void main(String[] args) {
    IntStream.range(1, 6).boxed().collect(Collectors.toList()).sort(reverse((x, y) -> x - y));
  }

  private static Comparator<Integer> reverse(Comparator<Integer> comparator) {
    return (x, y) -> comparator.compare(y, x);
  }

}

Reference

댓글남기기