2010-07-25 5 views
7

나는 컴파일러에서 clojure를 사용하려고 시도하므로 호출을 deftype으로 매개 변수화해야합니다. 그러나, 형식 힌트를 통해 수행하는 데 어려움을 겪고 있습니다. REPL에서Clojure deftype을 매개 변수화 된 함수로 사용하기

(defn describe [x] 
    (let [fields (.getDeclaredFields x) 
     names (map #(.getName %) fields) 
     types (map #(.getType %) fields)] 
    (interleave types names))) 

(defn direct [] (deftype direct-type [^int x])) 
(defn indirect-helper [] (list ^int (symbol "x"))) 
(defn indirect [] (eval `(deftype ~(symbol "indirect-type") ~(indirect-helper)))) 

그리고 다음 세션 : 다음 코드를 고려 간접 형에 대해 생성 된 클래스는^INT를 잃은 것을

Clojure 1.2.0-master-SNAPSHOT 
1:1 user=> #<Namespace dataclass> 
1:2 dataclass=> (direct) 
dataclass.direct-type 
1:3 dataclass=> (indirect) 
dataclass.indirect-type 
1:4 dataclass=> (describe direct-type) 
(int "x") 
1:5 dataclass=> (describe indirect-type) 
(java.lang.Object "x") 

공지 사항은 직접 형이 가지고 힌트. 그 힌트를 어떻게 전달할 수 있습니까?

답변

7

당신은

(defn indirect-helper [] [(with-meta (symbol "x") {:tag 'int})]) 

을 읽을 수 indirect-helper을 변경해야합니다 이유는 ^intint 다음 ^로 구문 분석하는 것입니다; ^은 Clojure 1.2에서 독자 메타 데이터를 소개합니다 (1.1에서는 #^을 사용했지만 여전히 작동하지만 1.2에서는 사용되지 않습니다). 따라서 direct^int x가 그의 이름 "x" 있고 그지도 메타 {:tag int}clojure.lang.Symbol으로에 리드를 얻는다합니다 (int 여기 자체 심볼되고 있음). (기호의 마지막 구성 요소 - 네임 스페이스 -이 경우 nil입니다.) ^int(symbol "x")에 부착됩니다 질문 텍스트에서 indirect-helper의 버전에서

- 기호 symbol 및 문자열을 포함하는 목록 "x" (특히 (list ^int (symbol "x"))은 1 요소 목록으로 평가 됨). (symbol "x")이 평가되면이 "유형 힌트"가 손실됩니다. 이 문제를 해결하려면 (symbol "x")에 의해 생성 된 실제 기호에 메타 데이터를 첨부하는 방법이 필요합니다.

이 경우 기호는 런타임에 생성되므로 독자가 메타 데이터를 사용하여 유형 힌트를 첨부 할 수 없습니다.

user> (indirect) 
user.indirect-type 
user> (describe indirect-type) 
(int "x") 

(BTW, 나는 deftype 필드 이름의 벡터를 기대 생각 : 런타임에 메타 데이터를 첨부합니다 (그리고 여기에 같은 이유로 매크로를 작성에 자주 유용)와 날이 저장됩니다 with-meta를 입력 , 분명히리스트도 잘 작동합니다 ... 벡터는 여전히 더 관용적입니다.)

관련 문제