[프로그래밍] 함수형 프로그래밍
함수형 프로그래밍
함수의 동작에 의한 변수의 부수적인 값 변경을 원천 배제함으로써 오류를 방지하는 패러다임
함수 내부에 상태가 존재하지 않으며, 함수의 출력 값은 항상 함수의 입력 값의 영향만 받는다
- 높은 표현력을 통해 불필요한 코드를 줄일 수 있다.
- 함수형 프로그래밍의 언어군은 프로그래밍 언어론의 최신 연구 결과를 반영하고 있다
- 불변성(Immutability)으로 인해 다양한 최적화 및 검증이 용이
- 이전에 계산한 함수의 값을 캐싱해 두었다가 필요할 때 다시 사용하는 메모이제이션이 가능
- 함수형 프로그래밍 언어에서는 변경 가능한 상태를 원천적으로 배제하기 때문에 멀티프로세서, 멀티스레드 환경에서 동작하는 동시성 프로그램을 개발할 때 용이
대표 함수형 프로그래밍 언어 : Scala, LISP, Haskell, F#, Erlang
일급 객체
다음 조건을 만족하면 일급 객체라고 할 수 있다.
- 변수나 데이터에 할당할 수 있어야 한다
- 객체의 인자로 넘길 수 있어야 한다
- 객체의 리턴값으로 리턴할 수 있어야 한다
즉, 객체처럼 동작할 수 있는 함수를 지칭한다
순수 함수
항상 같은 인풋에는 항상 같은 아웃풋(멱등성, 참조 투명성)
외부의 인자를 변화시키지 않고 최대한 지역변수만을 사용해서 구현되는 함수
고차 함수 = 고계 함수
함수를 값이라 생각하고 함수를 인자값으로 넣어주는 형태
인자로 다른 함수를 받아 결과값을 내보내는 함수를 의미
커링
여러 인자를 받는 함수에 일부 인자만 넣어서 나머지 인자를 받는 다른 함수를 만들어낼 수 있는 함수형 프로그래밍 기법을 의미
함수 합성
함수형 프로그래밍을 위한 라이브러리들에는 컬렉션 내 요소들을 다양하게, 연속적으로 처리할 수 있는 많은 도구
새로운 함수를 생성하거나 어떤 계산을 수행하기 위해 둘 이상의 함수를 결합하는 프로세스이다
재귀와 꼬리 재귀 최적화
모나드(Monad)
모나드는 값을 캡슐화하고, 추가 기능을 더해 새로운 타입을 생성하는 구조체
모나드는 하나의 타입이며 인자를 Type 타입으로 받아 값을 캡슐화하여 값을 가공할 수 있는 추가기능 오퍼레이터를 사용할 수 있는 Functor를 사용하여 최종적으로 이러한 프로세스를 구현하는 구조를 새롭게 생성하는 특징을 가지고 있다.
다음 세 가지를 충족하면 모나드라 할 수 있다.
- 타입을 인자로 받는 타입
- unit(return) 오퍼레이터가 있어야 한다
- bind 오퍼레이터가 있어야 한다
모나드가 필요한 이유 ?
비동기 연산 처리, NULL 처리
-
Map
컬렉션의 원소를 순회하는 방법의 의미보다
T 타입의 Functor를 R 타입의 Functor로 바꾸는 기능이라고 생각하는 중요! -
flatMap
위 맵의 역할을 하지만 캡슐화가 된 자료구조를 Serialize했다고 생각하면 편하다
import java.util.function.Function;
interface Functor<T>{
<R> Functor <R> map(Function<T, R> f);
}
# 1. 함수를 인자를 받는 map 메소드만 가진다
# 2. 타입 인자 <T>를 가짐
# 3. 전달인자인 함수 f는 <T> 타입 값을 받아 <R> 타입 값을 반환하는 함수
# 4. Functor는 map함수를 거쳐 <R> 타입의 Functor를 반환
map메소드로 값을 변경하는 것 뿐인데 왜 Functor를 사용할까?
=> Functor를 이용하면 일반적으로 모델링할 수 없는 상황을 모델링 할 수 있다.
- 타입안정성을 유지하면서 NULL을 인코딩하는 방법
- 아직 값을 가지고 있지 않아도 동일하게 map 메소드를 적용할 수 있음 (문법적으로나 의미적으로 완전 동일)
- 비동기 로직을 동기 로직을 구현하는 것과 동일한 형태로 구현하면서도, 함수의 합성 및 완전한 Non-Blocking Pipeline을 구현 가능
- Functor의 문제점
=> Functor가 Functor안에 감싸져 있으면, 함수의 합성과 체이닝을 저해하므로 제 기능을 하지 못하게 될 수 있음
Monad = Functor + flatMap
interface Monad<T, M extends Monad<?, ?>> extends Functor<T, M>{
M flatMap(Function<T, M> f);
}
지연 연산(Lazy Evaluation)
어떤 값이 실제로 쓰이기 전까지 그 값의 계산을 최대한 연기하는 것을 의미.
값을 미리 계산하여 저장하지 않기때문에 공간을 절약할 수 있고 값이 꼭 필요할 때만 계산하기 때문에 프로그램 성능에도 긍정적인 영향을 준다.
댓글남기기