Namespaces
Namespaces (네임스페이스)
Clojure 코드를 파일이나 REPL에서 다루다 보면, def로 정의한 변수라든가 import로 가져온 클래스가 "어디에 들어 있는지"를 늘 의식하게 돼요. 그 기준점이 바로 네임스페이스(namespace)예요. 이름이 같은 심볼도 서로 다른 네임스페이스에 있으면 충돌하지 않죠. 이 글에서는 네임스페이스가 정확히 무엇인지, 파일과 REPL에서 어떻게 만들고 전환하는지 살펴볼게요.
출처: Clojure 공식문서
본문
네임스페이스는 단순(qualify되지 않은) 심볼을 Var나 Class에 연결하는 매핑이에요. def나 그 변형을 쓰면 Var가 네임스페이스에 intern(등록)되는데, 이때 Var는 이름이 될 단순 심볼과 자신이 속한 네임스페이스에 대한 참조를 갖게 되고, 네임스페이스는 그 심볼을 같은 Var에 연결해요.
네임스페이스에는 다른 네임스페이스에 intern된 Var를 가리키는 연결도 들어갈 수 있어요. refer나 use로 Var를 가져오거나, import로 Class 객체를 가져오는 식이죠. 네임스페이스는 first-class여서 열거(enumerate)할 수 있고요, 또 동적이라 REPL 등에서 런타임에 만들고, 지우고, 수정할 수도 있어요.
파일 위에서 네임스페이스 만들기
Clojure 소스 파일 맨 위에 네임스페이스를 새로 구성하는 가장 좋은 방법은 ns 매크로를 쓰는 거예요. 기본적으로 ns는 java.lang의 클래스명과 clojure.lang.Compiler, 그리고 clojure.core의 함수들에 대한 연결을 담은 새 네임스페이스를 만들어 줘요. 그래서 파일 안에서는 별다른 설정 없이도 clojure.core의 함수를 바로 쓸 수 있어요.
REPL에서 네임스페이스 만들기
REPL에서는 in-ns를 쓰는 게 좋아요. 이 경우 새 네임스페이스에는 java.lang의 클래스명에 대한 연결만 들어가요. clojure.core의 이름을 쓰려면 (clojure.core/refer 'clojure.core)를 직접 실행해야 해요. REPL 시작 시점의 user 네임스페이스는 이미 이 작업이 되어 있는 상태예요.
현재 네임스페이스 *ns*
현재 네임스페이스를 가리키는 *ns*는 in-ns나 ns 매크로로만 설정해야 해요. 두 함수 모두 네임스페이스가 없으면 새로 만들어 주기 때문에, 직접 다른 방식으로 바꾸는 일은 피하는 게 좋아요.
더 알아보기
관련 함수들을 역할별로 정리하면 이래요.
- 네임스페이스 만들고 전환하기:
in-ns,ns,create-ns - 네임스페이스에 추가하기:
alias,def,import,intern,refer - 존재하는 네임스페이스 찾기:
all-ns,find-ns - 네임스페이스 살펴보기:
ns-name,ns-aliases,ns-imports,ns-interns,ns-map,ns-publics,ns-refers - 심볼에서 네임스페이스 얻기:
resolve,ns-resolve,namespace - 제거하기:
ns-unalias,ns-unmap,remove-ns
같이 보면 좋은 자료: