같은 인자를 넘겼는데 함수 결과가 호출 시각과 전역 설정에 따라 달라집니다. 순수 함수로 만들려면 무엇을 바꿔야 하나요?
잠깐, 답변을 보기 전에
먼저 내 말로 설명해 볼까요?
답변과 점검 포인트 펼치기답변 접기
구두 답변
정의를 외우기보다, 원리와 조건을 연결해 설명해 보세요.
순수 함수는 같은 입력에 항상 같은 결과를 내고, 호출 자체로 외부 상태를 바꾸거나 관찰하지 않는 함수입니다. 따라서 현재 시각을 직접 읽거나 전역 환율을 조회하거나 파일에 로그를 쓰는 함수는 결과 또는 외부 상태가 호출 환경에 의존하므로 순수하지 않습니다. 순수하다는 말은 함수가 유용한 일을 하지 않는다는 뜻이 아니라, 계산과 부수효과의 경계를 분리한다는 뜻입니다.
예를 들어 priceWithTax(price)가 전역 currentTaxRate를 읽으면 같은 가격도 설정 변경에 따라 달라집니다. 세율을 인자로 받아 priceWithTax(price, taxRate)로 계산하게 하면 계산 부분은 순수해집니다. 현재 시각이 필요하면 시각을 읽는 얇은 경계에서 시간을 값으로 얻어 순수 계산 함수에 전달하겠습니다. 계산 결과를 DB에 저장하거나 화면에 표시하는 일은 별도의 효과 단계가 맡도록 하면 테스트에서 입력과 결과를 직접 비교할 수 있습니다.
순수 함수는 캐시, 병렬 실행, 재시도, 테스트 격리에 유리하지만 모든 코드를 순수하게 만들 수는 없습니다. 네트워크·파일·DB·난수는 실제 시스템의 목적에 필요한 효과입니다. 효과를 없애기보다 효과가 발생하는 위치와 순서를 명확히 하고, 효과를 감싼 경계에서 실패·재시도·중복을 처리하겠습니다. 특히 전달한 객체를 몰래 수정하면 결과뿐 아니라 호출자의 상태도 바뀌므로, 함수의 순수성을 말할 때 입력 값 변경 여부도 확인해야 합니다.
환경을 값으로 바꿉니다
priceWithTax(price)가 전역 세율을 읽으면 같은 가격도 설정에 따라 달라집니다. 세율을 priceWithTax(price, taxRate)의 입력으로 받고, 현재 시각도 경계에서 한 번 읽어 calculateExpiry(now, policy)에 넘기겠습니다. 난수는 전역 생성기 대신 seed와 다음 상태를 값으로 전달하면 실패 실행을 재현할 수 있습니다. 목록을 정렬하거나 전달받은 객체를 수정하는 것도 결과 외의 관찰 효과이므로 새 컬렉션을 반환하거나 불변 입력을 사용합니다.
효과는 별도 순서로 관리합니다
DB 저장·로그·네트워크 호출은 제거할 대상이 아니라 계산 바깥의 효과입니다. 순수 계산은 동일한 값 입력으로 메모이제이션하거나 병렬 실행할 수 있지만, 가변 객체의 주소를 캐시 키로 쓰면 내용이 바뀐 뒤 잘못된 결과를 재사용할 수 있습니다. 따라서 값 기준 동일성과 입력 수명을 정합니다. 효과 단계에서는 저장 성공 뒤 이벤트 발행 실패, 재시도 중복, 부분 업데이트를 별도 계약으로 시험해 순수 함수의 예측 가능성을 외부 시스템의 원자성으로 과장하지 않겠습니다.
구체적인 경계 사례
같은 입력의 함수 호출을 그 결과값으로 치환해도 프로그램의 관찰 결과가 달라지지 않는 성질을 참조 투명성이라고 합니다. 예를 들어 세율이 명시된 계산을 한 번 계산해 재사용할 수는 있지만, 로그를 쓰는 함수를 결과로 치환하면 로그 횟수가 바뀌므로 같은 성질이 없습니다. 순수 함수도 잘못된 세율이나 반올림 정책을 받으면 잘못된 결과를 일관되게 내므로 순수성과 업무 정확성은 구분합니다.
외부에서 설정과 가격을 읽은 뒤 순수 함수로 결제 명령을 계산하고 저장하는 구조라면, 읽은 이후 가격이 바뀌는 경쟁은 여전히 남습니다. 계산 결과에 기준 버전을 포함하고 저장 시 조건부 갱신으로 검사해야 합니다. 계산을 두 번 실행해도 안전하다는 성질이 결제 요청을 두 번 보내도 안전하다는 뜻으로 확대되지 않게 하겠습니다.
득점 포인트
이해가 드러나는 지점을 확인해 보세요.
- 동일 입력·동일 결과와 외부 상태 변경 부재를 모두 설명한다.
- 시계·전역 설정·난수를 명시적 값으로 옮기고 입력 변경도 막는다.
- 순수 계산의 캐시 이점과 효과 계층의 순서·중복 문제를 구분한다.
감점 포인트
놓치기 쉬운 조건과 오해를 짚어 보세요.
- 값을 반환하기만 하면 전역 읽기와 입력 객체 변경도 순수하다고 한다.
- 현재 시각·난수·설정 의존성을 숨긴 채 동일 결과를 약속한다.
- 함수형 설계가 필요한 DB·네트워크 효과를 모두 제거해야 한다고 말한다.
더 파고들 거리
하나 더 질문하며 이해의 범위를 넓혀 보세요.
- 순수 계산 결과를 캐시하려는데 입력 객체가 가변입니다. 값 동일성·해시·캐시 무효화를 어떻게 정하나요?
- 난수를 쓰는 계산을 재현 가능한 함수로 만듭니다. seed와 다음 난수 상태를 어떻게 입출력으로 전달하나요?
- 부수효과가 여러 개일 때 실패 중간 상태와 재시도 중복을 어떤 테스트로 검증할까요?
득점·감점 포인트는 학습용 자기 점검 기준이며, 특정 회사의 실제 채점표가 아닙니다.
원리부터 공부하고 싶다면
답변을 보충하는 개념·예제·슈도코드를 읽어 보세요.