practice / blog

For personal blogging
1 stars 0 forks source link

상태를 가진 함수를 리턴하자 #2

Open practice opened 8 years ago

practice commented 8 years ago

아래 코드는 함수를 받아서 새로운 함수를 리턴하는 함수이다.

(defn person-collector [valid?]
  (let [valid-people (atom [])]
    (fn [person]
      (if (valid? person)
        (swap! valid-people conj person))
      @valid-people)))

역시 closure 얘기인데, 만들어진 함수가 내부적으로 상태를 유지하는 형태임을 알 수 있다.

;; 아래의 샘플 데이터가 있을 때
=> (def p1 {:first-name "john" :last-name "adams"})
=> (def p2 {:first-name "jungkwon" :last-name "chin"})
=> (def p3 {:first-name nil :last-name nil})

;; valid? 함수를 만들고
(defn first-name-valid? [person] (not (nil? (:first-name person))))

;; 함수를 리턴 받은 다음
(def first-name-valid-collector (person-collector first-name-valid?))

이제 실행하면

user=> (first-name-valid-collector p1)
[{:last-name "adams", :first-name "john"}]
user=> (first-name-valid-collector p2)
[{:last-name "adams", :first-name "john"} {:last-name "chin", :first-name "jungkwon"}]
user=> (first-name-valid-collector p3)
[{:last-name "adams", :first-name "john"} {:last-name "chin", :first-name "jungkwon"}]