클로져(Closure)에 대한 말들은 많다. 최근 핫하다고는 하지만 전산의 태동기부터 존재하던 문법이다. 1급 객체(First class Object)를 지원하는 언어는 자연스럽게 지원하지만 개념 자체를 이해 못하는 경우가 많다.

파이선과 연계해서 클로져(Closure)를 설명하는 좋은 설명이 있어서 소개하고자 한다.

Objects are data with methods attached, closures are functions with data attached.

객체는 메서드가 달라붙어 있는 데이타라면, 클로져는 데이타가 달라붙은 함수이다.

예제는

def make_counter():
  i = 0
  def counter(): # counter() is a closure
    nonlocal i
    i += 1
    return i
  return counter

c1 = make_counter()
c2 = make_counter()

print (c1(), c1(), c2(), c2())
# -> 1 2 1 2

위에서 보면 counter 라는 함수가 i 라는 데이타를 포함하고 있는 클로져(closure)다.

http://stackoverflow.com/questions/13857/can-you-explain-closures-as-they-relate-to-python

Closure 라고 들어 보셨는지요. 최근에 차기 Java 버젼에 포함되기를 많은 사람이 희망하였다가 무산 되서 실망의 글로 자바 관련 게시판들이 도배가 됐다고 합니다. 자 그러면 대체 클로져 (Closure) 란 무엇인지 위키피디아의 내용을 보기로 하겠습니다.


http://en.wikipedia.org/wiki/Closure_%28computer_science%29


어려운 내용들로 도배가 되어 있습니다. 쭈욱 살펴보자면 함수를 리턴하는 언어들에게서 흔히 찾아 볼 수 있는 개념이고요. Anonymous Function 하고 착각하면 안된다고 쓰여져 있습니다. 즉 'function value' 개념이라는 식으로 언급이 되어 있습니다.


가장 쉽게 설명하자면 '지역 변수' 가 코드가 쓰여질 때의 값으로 지정되는 것이 아니라 '클로져'가 생성될 때 그 '값'에 접근이 가능하다? 라는 식으로 쓰여질 수가 있겠습니다. 


이러니 저러니 해도 여러가지 형태가 결부되어 있지만 , 


1. 함수가 리턴 되어야 하고

2. variable 이 관련 있어야 한다. (이것이 관련 없으면 클로져가 아니다)



아무래도 정말 쉽게 설명 하자면 예제 케이스를 가지고 설명하는 것이 가장 쉬울 것 같습니다.

EDITED. 2012 - 09 - 04

아무래도 Lisp 의 방언인 Clojure 로 설명을 하니 못 알아먹겠다는 원성이 자자해서 위키 페이지에 나와 있는 자바스크립트를 예로 설명드리겠습니다. 

function derivative(f, dx) {
  return function (x) {
    return (f(x + dx) - f(x)) / dx;
  };
}

함수 derivative 는 f 라는 함수와 dx 라는 변수를 입력받아서 , x 라는 인자를 받아서 처리하는 함수를 리턴하는 함수 입니다. 

리턴되는 function(x) 는 derivative 에서 넘겨받은 f 와 dx 에 영향을 받을 수밖에 없겠지요? 즉 리턴되는 function (x) 는 어찌 되었든 간에 derivative 에서 넘겨 받는  f 와 dx 에 의존해서 구현이 달라집니다. 이때 function(x) 가 derivative 의 인자인 f 와 dx 와 클로져 (Closure) 다 라고 합니다. 



클로져 (Clojure) 로 만든 Closure 의 예입니다. (발음이 같은 이유는 바로 관련이 있기 때문입니다)  함수를 세분해서 설명하겠습니다.


user> (defn make-greeter [greeting-prefix]
        (fn [username] (str greeting-prefix ", " username)))
#'user/make-greeter


make-greeter 라는 함수를 리턴하는 함수입니다. greeting-prefix 값을 받아서 그 값을 이용하는 함수를 리턴합니다.
defn 은 함수 선언을 지정하는 함수이고요. fn 은 내부 함수 선언용입니다. (str greeting-prefix ", " username) 이 부분 greeting-prefix 랑 " , " username 을 합쳐서 리턴하는 명령 입니다.

user> (def hello-greeting (make-greeter "Hello"))
#'user/hello-greeting

make-greeter 에 "Hello" (greeting-prefix 값이 "Hello" 가 됩니다) 를 인자로 넘겨서 반환되는 함수를 hello-greeting 으로 지정해 줍니다.

user> (hello-greeting "crazia")
"Hello, crazia"
user>

완성된 함수를 테스트 해봅니다.  greeting-prefix 값이 변함에 따라서 전혀 다른 함수가 만들어 집니다. "Hello" 대신 "Hi " 를 넣어서 리턴되는 함수는 또 다른 함수가 되겠지요? 자 이때!!!

make-greeter 에 의해서 리턴되는 함수가 greeting-prefix 값 에 대한  closure 다

이라고 합니다.


+ Recent posts