[clojure] 커링된 함수를 이용한 데이터 변환

커링(currying)은 여러 개의 인수를 받는 함수를 하나의 인수만 받는 함수들의 연결로 나타내는 방법입니다. 이 기법은 함수형 프로그래밍에서 유용하게 활용됩니다. 이번 글에서는 Clojure에서 커링된 함수를 이용하여 데이터 변환을 하는 방법에 대해 살펴보겠습니다.

커링(currying)

커링은 다음과 같이 여러 개의 인수를 받는 함수를 각각 하나의 인수만 받는 함수로 바꾸는 과정을 말합니다.

(defn add [x y]
  (+ x y))

(def add-curried (partial add))

위 예제에서 add-curried 함수는 add 함수를 부분적용하여 두 개의 인수를 받던 함수에서 한 개의 인수를 받는 함수로 만든 것입니다.

커링된 함수를 이용한 데이터 변환

데이터 변환이 필요한 경우, 커링된 함수를 이용하여 간결하고 유연한 방식으로 처리할 수 있습니다. 예를 들어, 다음과 같은 리스트가 있다고 가정해보겠습니다.

(def data [{:name "Alice", :age 25}
           {:name "Bob", :age 30}
           {:name "Charlie", :age 35}])

위 리스트를 다음과 같이 변환하고 싶다고 가정해보겠습니다.

[{:name-upper "ALICE", :age 25}
 {:name-upper "BOB", :age 30}
 {:name-upper "CHARLIE", :age 35}]

커링된 함수를 사용하면 이러한 데이터 변환이 간단해집니다.

(defn update-name [f person]
  (assoc person
         :name-upper ((f :name) person)))

(defn update-names [f data]
  (map (partial update-name f) data))

(def uppercase-name 
  (partial -> 
           :name 
           (partial str/split #"\s+")
           (partial apply str/upper-case)))

(update-names uppercase-name data)

위 코드에서 update-name 함수는 person 맵의 :name 값을 변환하는 함수를 받아 해당 맵을 업데이트하는 함수입니다. update-names 함수는 update-name 함수를 부분적용하여 데이터 전체에 대해 적용하는 함수입니다. 마지막으로 uppercase-name 함수는 :name을 대문자로 변환하는 함수를 만드는데, 이 함수를 update-names에 대입하여 모든 이름을 대문자로 변환했습니다.

이처럼 커링된 함수를 이용하여 데이터 변환 과정을 모듈화하고 재사용할 수 있게 되었습니다.

결론

Clojure에서 커링된 함수를 이용하여 데이터 변환을 간결하고 유연하게 처리할 수 있습니다. 데이터 변환 로직을 별도의 함수로 분리하여 모듈화하고 재사용함으로써 코드의 가독성과 유지보수성을 향상시킬 수 있습니다.

참고 자료: https://clojure.org/guides/learn/functions#_currying