2010-07-25 15 views
7

के रूप में क्लोजर डेफ्टाइप का उपयोग करके मैं एक कंपाइलर में क्लोजर का उपयोग करने की कोशिश कर रहा हूं और इस प्रकार 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)))) 

और आरईपीएल से निम्नलिखित सत्र:: निम्नलिखित कोड पर विचार करें

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

आप indirect-helper बदलने के लिए

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

को पढ़ने के लिए की आवश्यकता होगी कारण यह है कि ^int^int के बाद के रूप में पार्स करता है; क्लोजर 1.2 में ^, पाठक मेटाडाटा प्रस्तुत करता है (1.1 में आप #^ का उपयोग करेंगे, जो अभी भी काम करता है, लेकिन 1.2 में बहिष्कृत है)। इस प्रकार direct में ^int x एक clojure.lang.Symbol जिसका नाम "x" है और जिनका मेटाडेटा नक्शा {:tag int} है के रूप में में पढ़ा हो जाता है (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, जो रनटाइम पर मेटाडाटा देता है (और इसी कारण इसे यहाँ है के रूप में के लिए मैक्रो लिखित रूप में अक्सर उपयोगी है) और दिन सहेजा जाता है दर्ज करें , लेकिन स्पष्ट रूप से एक सूची भी काम करती है ... एक वेक्टर अभी भी निश्चित रूप से अधिक मूर्खतापूर्ण है।)

संबंधित मुद्दे