2022. 9. 19. 00:00ㆍCSharp/Functional Programming
동일한 input 에 대해 항상 같은 값을 output 하는 함수
매개변수가 같다면 return 값이 항상 같은 함수를 말한다.
특징
- side effect 가 없다. side effect 란 함수 내에서 함수 외부와의 모든 상호 작용, 함수 외부 변수를 변경하거나 다른 함수를 호출 하는 것.
- 일관성이 있다. 결과는 입력값에 의해서만 결정된다.
side effect 의 예
- 전역 상태 변경 – 예를 들어 인스턴스 필드.
- 인수 또는 외부 변수 변경.
- I/O 또는 HTTP 요청을 수행.
- 현재 시간을 가져오는 것.
아래 method 는 pure function 의 예이다.
private string Hello(string name) => $"Hello, {name}"; // pure function
Hello function 은 name 이 같은 이상 항상 같은 값을 return 한다. (순수함수)
만약 여기에 side effect 가 있는 datetime 이 들어간다면 impure function 이 된다.
private string HelloWithTime(string name) => $"Hello, {name}, {DateTime.Now}"; // impure function
HelloWithTime function 은 name 이 같아도 실행할때 마다 다른 값을 return 한다.
DateTime.Now 가 state 가 되어 side effect 를 발생 시킨다. (impure function)
이러한 pure, impure 를 구분하고 functional programming 에서 pure function 을 선호하는 이유는
내부상태가 없기 때문에 유지 보수가 쉽고 확장이 편리하기 때문이다.
parallel 작업을 한다고 가정해보고 아래 예제를 확인하자
여러 사람들이 이름이 있는 list 가 있다고 하자
해당 list 에 이름들을 대문자로 바꾸고 내부함수를 통해 counter 를 계산하여 No 를 정해주는 함수가 있다고 하자
c# 으로 구현하면 아마 아래와 같을 것이다.
Impure function counter
var names = new List<string>() { "John", "Melcy", "Thor" };
int counter = 1;
string Format(string s) => $"{counter++}) {s}"; // 내부 함수
List<string> result = names
.Select(x => x.ToUpper())
.Select(Format)
.ToList();
이제 이 함수를 병렬화 해보자
...
List<string> result = names
.AsParallel() // <--- parallel 추가 하여 병렬 처리
.Select(x => x.ToUpper())
.Select(Format)
.ToList();
...
그리고 값을 찍어보면 우리가 예상한것과 다른 값들이 나온다.
...
2) JOHN,1) MELCY,3) THOR
2) JOHN,3) MELCY,1) THOR
3) JOHN,1) MELCY,2) THOR
...
카운터를 읽고 업데이트하는 여러 스레드가 있어 결과를 예측할 수 없게 된다.
순수함수 형태로 함수를 변경하여 이 문제를 해결해 보자
Pure function counter
var names = new List<string>() { "John", "Melcy", "Thor" };
List<string> result = names
.AsParallel()
.Select(x => x.ToUpper())
.Zip(ParallelEnumerable.Range(1, names.Count), (name, c) => $"{c}) {name}")
.ToList();
위와 같이 zip 을 통해 format 이라는 내부함수를 대체 하고 counter 라는 state 를 삭제였다.
이로인해 side effect 가 제거 되었고 순수함수로 변경되었다.
관련영상
'CSharp > Functional Programming' 카테고리의 다른 글
Semigroup (2) | 2022.09.21 |
---|---|
Magma (2) | 2022.09.20 |
Expression, Method chaining with Extension methods (0) | 2022.09.16 |
Functors (Map, Filter, Reduce) (0) | 2022.09.15 |
Higher Order Function (0) | 2022.09.14 |