Search
Duplicate
📒

[Java Study] 10-x. 함수형 프로그래밍

상태
미진행
수업
Java Study
주제
기본개념
4 more properties
참고

시스템 구현과 유지보수

NOTE
함수형 프로그래밍은 부작용 없음(사이드 이펙트)불변성이라는 개념으로 유지보수성을 향상시켜준다!
유지보수에서 코드 크래시 디버깅 문제를 일으키는 요소는 예상하지 못한 변수값 때문이다.
함수형 프로그래밍이 이러한 변수값이 바뀌는걸 막아줌!
변수가 예상하지 못한 값을 가지는 이유는, 유지보수하는 시스템의 여러 메서드에서 공유된 가변 데이터 구조를 읽고 갱신하기 때문이다.
자신을 포함하는 클래스의 상태 그리고 다른 객체의 상태를 바꾸지 않으며 return문을 통해서만 결과를 반환하는 함수를 순수 메서드, 부작용 없는 메서드라고 부른다.
⇒ 이러한 방식을 함수형 프로그래밍이라 한다!
구체적으로 부작용은 무엇일까?
자료구조를 고치거나 필드에 값을 할당
예외 발생
파일에 쓰기 등의 I/O 동작 수행
불변 객체를 이용해서 부작용을 없애는 방법도 있다.
불변 객체는 복사하지 않고, 상태를 바꿀 수 없으므로 쓰레드 안전성을 제공한다.

함수형 자바

NOTE
실질적으로 자바로는 완벽한 함수형 프로그래밍을 구현하기 어렵다!
예외가 발생하는 함수는 함수형이 아니다.
함수나 메서드는 지역 변수만을 변경해야 함수형이라 할 수 있다.
함수나 메서드에 참조하는 객체가 있다면 그 객체는 불변 객체여야 한다.
함수나 메서드가 어떤 예외도 일으키지 않아야 한다.
예외가 발생하면 return으로 결과를 반환할 수 없기 때문

예외없이 나눗셈을 표현하려면?

Optional<T>를 사용해서 해결할 수 있다.
혹은 지역적으로만 예외를 사용해서 해결할수도 있다.

참조 투명성

NOTE
같은 인수로 함수를 호출했을 때 항상 같은 결과를 반환한다면 참조적으로 투명한 함수라 한다!
참조 투명성은 프로그램 이해에 큰 도움을 주며, 오랜 시간이 걸리는 연산을 기억화 또는 캐싱을 통해 다시 계산하지 않고 저장하는 최적화도 제공한다.

객체지향 프로그래밍과 함수형 프로그래밍

NOTE
같은 인수로 함수를 호출했을 때 항상 같은 결과를 반환한다면 참조적으로 투명한 함수라 한다!
데이터를 함수로 연결하는 것을 중심으로 사고하는 방식( 함수형 프로그래밍)
프로그래밍 형식을 스펙트럼으로 표현하자면 스펙트럼의 한 쪽끝에는 모든 것을 객체로 간주하고, 객체를 갱신하는 방식으로 동작하는 익스트림 객체지향이 위치한다.
반대쪽 끝에는 참조적 투명성을 중요시하는, 즉 변화를 허용하지 않는 함수형 프로그래밍 형식이 위치한다.

재귀와 반복

NOTE
순수 함수형 프로그래밍 언어에서는 for, while 같은 반복문을 포함하지 않는다!
static long factorialRecursive(long n) { return n == 1 ? 1 : n * factorialRecursive(n-1); }
Java
복사
하지만 재귀는 반복보다 비싸다.
호출마다 스택이 증가함
반복에 의한 변화가 코드에 스며들 수 있기 때문이다.
일반적으로 반복 보다 재귀 코드가 더 비용이 높다.
재귀 입력값에 비례해서 메모리 사용량이 증가한다.
큰 입력값을 넣으면 StackOverflowError가 발생

그러면 재귀는 쓸모가 없는가?

static long factorialTailRecursive(long n) { return factorialHeper(1, n); } static long factorialHelper(long acc, long n) { return n == 1 ? acc : factorialHelper(acc*n, n-1); }
Java
복사
함수형 언어에서는 꼬리 호출이라는 해결책을 제공한다.
꼬리재귀를 통해 컴파일러가 하나의 스택 프레임을 재활용할 가능성이 생기도록한다.

자바 8에서는 반복을 스트림으로 대체하여 변화를 피한다.

반복 → 재귀로 바꾸면 더 간결하고 부작용이 없는 알고리즘을 만들 수 있다.
약간의 실행 시간보다, 프로그래머의 효율성이 더 중요할 때도 많다.