본문 바로가기

카테고리 없음

쏙쏙들어오는 함수형 코딩과 jojoldu의 멱등성 토론 (마음속에서) 해결!

2022년 10월 5일 프론트엔드 스터디로 《함수형 코딩》이라는 부분을 한다고 해서 급하게 스터디에 참여했다.

첫 시간이라서 1장 소개 부분이 진행햇다.

 

1장에서는 함수형 프로그래밍에 대하여 개념을 소개하면서 액션, 계산, 데이터를 구분하는 것을 설명한다.

  • 액션: 실행 시점이나 횟수 또는 둘 다에 의존하는 것
  • 계산: 입력값으로 출력값을 만드는 것. 같은 입력값을 가지고 계산하면 항상 같은 결괏값이 나오는 것. 언제, 어디서 계산해도 결과는 같고 외부에 영향을 주지 않음. 테스트하기 쉽고 언제든지 몇 번을 불러도 안전. => 멱등
  • 데이터: 이벤트에 대해 기록한 사실. 실행하는 코드만큼 복잡하지 않기 때문에 다른 것과 구분.

위의 설명으로는 직관적이지 않기에 "함수형 프로그래머는 실행하는 코드와 그렇지 않은 코드를 구분합니다."의 분류의 예는 이해에 도움이 된다.

구분 설명
액션
action
액션은 부르는 시점에 의존 sendEmail(to, from, subject, body)
saveUserDB(user)
getCurrentTime()
계산
calculation
계산은 입력값을 계산해 출력하는 것 sum(numbers)
stringLength(str)
데이터
data
데이터는 이벤트에 대한 사실을 기록한 것 [1, 10, 2, 45, 3, 98]
{"firstName": "Eric", "lastName": "Normand"}

참고로 《함수형 코딩》 에서는 멱등(idempotent)이라는 용어가 아예 나오지 않는다.

하지만 이미 항상 같은 결괏값이 나오는 것에서 언급한 것 처럼 계산이 바로 멱등한 대상임은 자명하다.

액션은 멱등하지 않는 것이다.


다시 이동욱 님의 블로그로 돌아가서 "Spring Batch의 멱동성 유지하기" 글의 내용은 아래와 같다.

배치 애플리케이션에서는 다음과 같은 배치 처리의 예를 들고 있다.

  • 매일 한번 어제 매출 데이터를 집계해야할 때
  • 현재 시간을 기준으로 유효기간이 만료된 포인트를 정리할 때
  • 매일 한번 오늘을 기준으로 휴면회원 처리를 할 때

해당 블로그에서는 멱등성이 깨진 이유에 대해 제어할 수 없는 코드가 내부에 있기 때문이라고 설명을 하였다.

  • new Scanner(System.in)
  • LocalDate.now()
  • new Random()

함수형 코딩에서 언급한 액션, 계산, 데이터에서 즉 액션에 해당하는 것인 셈이다.

이동욱 님은 해당 문제를 해결하는 과정에서 시간이라는 것을 데이터(파라미터)로 바꾸면서 멱등성 유지를 해서 해결을 했다고 하였다.

 

처음 달았던 댓글에서 나는 액션, 계산, 데이터라는 구분하는 용어는 몰랐지만 그것들의 존재는 알았던 것으로 생각한다.

그 이유는 포인트를 정리하기 위해 대상을 나누는 작업은 계산이지만 정리하는 것은 DB 등에 수정을 가하는 액션이기 때문이다.

또한 휴면회원 처리에서 휴면회원에 대해 판단하는 부분은 계산이지만 회원 정보를 읽어오는 것과 휴면회원 처리를 하는 것은 액션이다.

 

이동욱 님은 Spring Batch의 Processor 가 수행하는  계산 부분에서 시간을 분리해서 멱등이 이루어지게 했다고 생각을 했다.
하지만 배치 작업에는 Reader / Writer 가 수행하는 액션이라는 작업 부분을 완전히 제거할 수가 없었을 것이다.

따라서 멱등성은 이루어질 수 없는 것이다.

 


또 다른 관점은 파라미터로 분리된 날짜 데이터는 어디에선가 만들어져야 하는 시간이라는 것이다.

Java 애플리케이션이 시스템에서 획득하던, Jenkins가 시스템에서 획득하여 Java 애플리케이션의 파라미터로 전달하던 말이다.

 

《함수형 코딩》에서도 옮긴이 머릿말에 이런 말이 나온다.

하스켈 개발자가 아닌 사람들은 하스켈과 같은 순수 함수형 언어는 부수 효과마저 순수한 함수로 표현하기 때문에 부수 효과가 없다고 오해하기도 합니다. 하지만 부수 효과를 단지 미루는 것뿐이고 결국 부수 효과는 발생합니다. 부수 효과가 없는 소프트웨어는 의미가 없기 때문입니다.

관련된 후자의 내용은 이미 https://namocom.tistory.com/752 에서 언급했기에 생략한다.

부수 효과를 Spring batch 에서 Jenkins로 미루었다!


2년이 지나서 이 토론은 머릿속 한 편에 남아 있었던 것 같다.

뭔가 막연하게 알던 개념에 대해 좀 더 명쾌하게 설명을 할 수 있게되어 뭔가 후련한 느낌이 들어서 혼자만 알고 있기 아까워서 오랫만에 블로그에 글을 작성했다.

현재 나의 느낌을 한 그림으로 표현하면 딱 이것!