클로저(Closure) 는 Clojure의 프로그래밍 패턴 중 하나로, 바깥 렉시컬 스코프에 있는 변수를 함수 안에서 사용할 수 있게 해줘요. Clojure는 클로저를 자연스럽게 지원하고, 클로저가 무엇인지 모르는 채로 쓰는 경우도 많아요.
;; Top-level definitions are global-scope
(def dozen 12)
;; Functions create a new scope.
;; Referencing the outer variable here is a closure.
(fn [n] (* dozen n))
atom을 사용하면 상태를 보존할 수 있어요:
;; This function closure increments the counter's state
;; in the outer lexical context.
;; This way the counter can be shared between many calling contexts.
(def increment
(let [counter (atom 0)]
(fn [] (swap! counter inc))))
increment를 호출할 때마다 카운터가 하나씩 증가해요:
(increment)
;;=> 1
(increment)
;;=> 2
디자인 회사에서는 주로 CSS 변환을 사용해 웹 페이지를 만들어 왔어요. 몇 가지 논의 끝에, 일부 계산을 동적으로 수행하기 위해 Clojure를 사용하기로 했어요. 팀원 중에는 Clojure가 아직 익숙하지 않은 사람도 있어서, {x, y} 좌표 쌍을 위한 재사용 가능한 변환을 만들기 위해 함수 클로저를 사용하기로 했어요.
translate2d 함수를 구현해요. 이 함수는 클로저를 사용해 좌표 쌍을 반복해서 2차원 평행 이동하는 함수를 반환해요.
(def move-coordinates-right-2px (translate2d 2 0))
(def result (move-coordinates-right-2px 4 8))
;; result => [6 8]
scale2d 함수를 구현해요. 이 함수는 클로저를 사용해 좌표 쌍을 반복해서 2차원으로 크기 조정하는 함수를 반환해요.
이 연습 문제에서는 양수 크기 조정 값만 있다고 가정해요.
(def double-scale (scale2d 2 2))
(def result (double-scale 6 -3))
;; result => [12 -6]
두 변환 함수를 결합해 반복 가능한 변환을 수행해요. 이를 보통 _함수 합성_이라고 하는데, 첫 번째 함수 'f(x)' 의 결과가 두 번째 함수 'g(x)' 의 입력으로 사용돼요.
(def move-coordinates-right-2px (translate2d 2 0))
(def double-coordinates (scale2d 2 2))
(def composed-transformations
(compose-transform move-coordinates-right-2px
double-coordinates))
(def result (composed-transformations 0 1))
;; result => [4 2]
memoize-transform 함수를 구현해요. 이 함수는 _메모이제이션_할 함수를 받아서, 전달받은 함수의 입력을 기억하는 새로운 함수를 반환해요. 그래야 같은 인자로 다시 호출했을 때 마지막 반환 값을 "기억"하고 한 번만 계산해요.
메모이제이션은 _동적 계획법_이라고도 하는데, 연산 결과를 기억해 두기 때문에 비용이 큰 연산을 한 번만 수행할 수 있어요.
(def triple-scale (scale2d 3 3))
(def memoized-scale (memoize-transform triple-scale))
(memoized-scale 4 3)
;; => [12, 9], this is computed since it hasn't been computed before for the arguments
(memoized-scale 4 3)
;; => [12, 9], this is remembered, since it was computed already
Exercism에 가입하고 Clojure 트랙을 개념 12개연습 문제 105개, 그리고 실제 사람의 멘토링과 함께 배우고 익혀 보세요. 모두 무료예요.