Practice/Lisp

Lisp에서 클로저(closures)

클로저란 함수가 lexical[각주:1] 환경(environment)의 변수를 참조하는 것을 말한다.


예를 들면, 아래 코드를 살펴보자.

(defparameter *plus-10* (let ((x 10)) (lambda (y) (+ x y))))

X와 Y를 더하는 함수 객체를 만들고, *PLUS-10*이 이를 가르키게 한다.


Lexical 변수 X는 LET 구문 블럭이 생성한 환경에 갇혀서 외부에서는 접근할 수 없다.
LET 구문 블럭이 종료되었다는 것은 실행 흐름이 LET이 생성한 환경에서 벗어났다는 것을 의미한다.
그럼에도 불구하고, *PLUS-10*를 호출하면 X 변수를 참조할 수 있다.

CL-USER> (funcall *plus-10* 20)
30


함수 객체가 다른 곳(예제에서는 dynamic 환경의 *PLUS-10*)에서 참조되고 있으면,
이 함수 객체가 속한 환경 역시 사라지지 않는다.
변수(예제에서는 X)를 만나면 자신이 속한 환경을 거슬러 올라가며 찾는다.


함수의 호출 과정에서도 lexical 변수를 생성한다.
함수의 환경을 생성하고, 이 환경에 메인 함수의 인자를 생성하여, 전달받은 값을 참조하게 한다.


이것을 응용하면 좀 더 재미있는 함수를 만들어볼 수 있다.

(defun plus-x (x) (lambda (y) (+ x y)))

PLUS-X 함수는 고정된 어떤 값을 더하는 함수를 자유자재로 만들 수 있다.[각주:2]
15를 더하는 함수를 다음과 같이 만들 수 있다.

(defparameter *plus-15* (plus-x 15)


이와 같이 lexical 환경에서 정의된 함수가 lexical 변수를 참조하는 것을 클로저라고 한다.


2016/02/18 - [Practice/Lisp] - Lisp에서 lexical과 dynamic 변수 타입


  1. lexical이 무엇인지는 <a href="http://unipro.tistory.com/190" target="_blank">Lisp에서 lexical과 dynamic 변수 타입</a>를 참고하라. [본문으로]
  2. curring과 비슷한 개념이라고 생각하면 되겠다. [본문으로]
저작자 표시 변경 금지
신고
크리에이티브 커먼즈 라이선스
Creative Commons License

알림

이 블로그는 구글에서 제공한 크롬에 최적화 되어있고, 네이버에서 제공한 나눔글꼴이 적용되어 있습니다.

카운터

Today : 77
Yesterday : 122
Total : 164,453

티스토리 툴바