함수의 순수성을 보장했을때의 장점

Raymond Yoo·2023년 12월 11일
0
post-thumbnail

'순수 함수(pure function)' 라는 것에는
또다른 의미가 숨어있다. 순수 함수는
함수를 구현할때 필요한 모든 정보를
항상 파라미터를 통해서 얻고
함수를 실행한 뒤에 얻은 결과를 언제나 리턴값으로 내보낸다.

순수 함수를 Lookup Table 로 그려서 설명하기

그렇기 때문에 모든 순수 함수는
언제나 Lookup Table 로 치환해서 생각할 수 있다.
어떤 함수가 순수 함수인지 아닌지를 판단하는 기준은
함수의 입력값, 출력값 쌍을 Lookup Table 로 표현할 수
있는지 없는지가 된다.

이렇게 구현한 순수 함수는
프로그래머에게 아주 다양한 이점을 제공한다.
훨씬 많은 장점이 있겠지만 여기서는 우선
네 가지를 소개해보겠다.

  • (1) Memoization 최적화 가능
  • (2) Lazy Evaluation 최적화 가능
  • (3) Parallel Processing 적용하기에 편함
  • (4) 테스트 작성이 훨씬 용이해짐

(1) Memoization 최적화

Memoization 은 값을 미리 계산해두는 것이다.
입력값에 따른 출력값이 정해져있기 때문에
컴퓨팅 리소스에 여유가 있을때
계산 결과값을 미리 저장해두면
나중에 실제로 함수를 호출해서 리턴값을 확인하려는 순간에
런타임 실행시간을 줄일 수 있다.

이런 논리를 극단적으로 추구하면
컴파일타임 프로그래밍(compile-time programming)
영역에 도달한다. 런타임에 하는 일의 상당부분을
전부 컴파일 타임에 계산해서 저장해두거나
아예 텍스트 자체를 치환하므로서
런타임에 실시간으로 발생하는 부하를 거의 0 으로 만드는 기법이다.

(2) Lazy Evaluation 최적화

Lazy Evaluation 은
함수를 호출하는 순간에 입력값에 대한 연산을 하는 대신에
함수의 반환값을 사용하려는 순간에
실제 연산을 실시하도록 만들어서
최대한 lazy 하게 동작하도록 만드는 기법이다.
입력값으로 아주 많은 양의 데이터를 넘겨서
함수를 호출하는 경우에 유용하다.
예를 들어서 f(L) 과 같이
리스트를 파라미터로 받는 함수가 있다고 가정해보자. 이 함수는
리스트의 각 요소에 대해서 어떤 처리 X 를 적용한 뒤에
결과를 같은 개수의 요소로 이루어진 리스트에 담아서 반환한다.
겉보기에는 문제가 없어보이지만
입력값으로 길이가 1000만 정도 되는 리스트를 받는다고 생각해보면
프로그램이 이 함수를 호출하는 부분에서 동작이 꽤나 오랫동안
blocking 상태로 있을꺼라는 걸 쉽게 짐작할 수 있다.
이와 같은 상황에서 lazy evaluation 원리를 적용하면
런타임 부하를 "X 처리 하나" 를 완료하는데
걸리는 만큼으로 시간복잡도를 줄일 수 있다.
lazy evaluation 의 대표적인 예시가 generator 이다.

이런 원리를 적용해서
함수의 입출력 파라미터를 Stream 타입으로 지정해서 구현하면
제한된 컴퓨팅 리소스를 가지고
사실상 무한대를 다루는 것이 가능해진다.

(3) Parallel Processing 적용

순수 함수는 입력값, 출력값이 고정되어 있으므로
연산 순서에 따라서 실행결과가 달라지지 않는다.
순수 함수의 이러한 특성에 대해서 곰곰히 생각해보면
엄청나게 많은 입력값에 대해서
병렬처리가 가능하겠구나 하는 결론에 이를 수 있다.
길이가 1000만 인 리스트의 요소를 하나씩 처리하는 대신에
100만개씩 나눠서 처리할 수 있다면
한 개의 손이 일하는 것보다는 열 개의 손으로 일하는게
작업 속도가 훨씬 빠를거라는건 꽤나 명확하다.

물론 순차처리보다 병렬처리가 언제나 효율적인 것은 아니기 때문에
연산에 대한 메트릭을 실제로 측정해서
더 나은 옵션을 선택해야 한다.

(4) 테스트 작성이 용이해짐

Mock, Fake 객체를 사용하는 런던파 스타일이 아니고
실제 시스템을 사용해서 자동화된 테스트 코드를 실행하는
고전파 스타일을 선택한다면
테스트 코드를 실행하는 컨텍스트(시점, 환경설정 등)에 따라서
flaky test 가 되는 경우를 종종 발견할 것이다.
하지만 순수 함수에서는 그런일이 발생하지 않는다.
함수의 구현내용은 온전히 파라미터 입력값에 의존하기 때문이다.
개발자 입장에서 고려해야 할 사항이 하나 둘 줄어들기 때문에
테스트 코드를 작성하는 과정이 훨씬 덜 고통스러워진다.

이렇게 순수 함수의 장점을 네 가지 알아봤다.
여기서는 미처 생각하지 못했지만 다른 장점들이 또 있을 수 있다.

평소에 구현을 할때 함수의 순수성, 변수의 불변성이라는 특성을
항상 스스로에게 환기시키며 작업한다면 완성한 프로그램이
훨씬 안정적이고 유지보수하기 쉽다는 것을 느끼게 될 것이다.

<참조>
유뷰트 영상, Functional Programming for Pragmatists • Richard Feldman • GOTO 2021

profile
세상에 도움이 되고, 동료에게 도움이 되고, 나에게 도움이 되는 코드를 만들고 싶습니다.

0개의 댓글