2012-04-09 15 views
30

में सामान्यीकृत थ्रेडिंग मैक्रो नोट: यह समरूपता के बारे में नहीं है। यह थ्रेड मैक्रो के बारे में है।क्लोजर

मुझे पता है कि -> ऑब्जेक्ट को दूसरी स्थिति में रखता है और ->> अंतिम स्थिति पर तर्क डालता है।

अब, मैं उत्सुक हूँ, बहुत कार्यों के लिए #(... %) से कम हाथ अंकन की तरह, मुझे मनमाना स्थान पर तर्क जगह देता है कि धागे के लिए एक छोटी हाथ अंकन है?

लक्ष्य यह होगा कि धागे के माध्यम से चलाने के लिए एक निश्चित स्थान होने के बजाय ... मैं मनमानी रूपों को लिख सकता हूं, और विशेष स्थानों पर %% डाल सकता हूं, और %% वह जगह है जहां थ्रेड डाला जाता है।

धन्यवाद!

+0

प्रश्न के लिए धन्यवाद। मैं उम्र के लिए पूछना चाहता हूं। कभी-कभी मुझे (# (func-adapter arg1% arg2) का उपयोग करना पड़ता है) -> या - >> के साथ प्रभाव प्राप्त करने के लिए। – jbear

उत्तर

26

Swiss Arrows पुस्तकालय से 'हीरे की छड़ी' आप जो चाह रहे हैं करना होगा:

(-<> 0 
(* <> 5) 
(vector 1 2 <> 3 4)) 
; => [1 2 0 3 4] 

कहा, यह मेरी Clojure अनुभव में कुछ (या कभी आप अंत अक्सर की जरूरत नहीं है)

+9

मुझे यह पसंद है कि ये मैक्रोज़ क्लोजर वेरिएबल नामों की लचीलापन का दुरुपयोग कैसे करते हैं –

+2

अभी तक बेहतर संस्करण 1.5 के रूप में, क्लोजर 'as->' प्रदान करता है जैसा कि [अन्य उत्तर] में बताया गया है (http://stackoverflow.com/a/17635433/109618)। –

+0

मैं 'as->' का उपयोग अक्सर करता हूं, लेकिन मुझे हीरे की छड़ी की संक्षिप्तता और दृश्य स्पष्टता पसंद है। आम तौर पर तब होता है जब अलग-अलग धर्मार्थियों जैसे 'मानचित्र' और 'assoc' के साथ सामान्य कार्य समान थ्रेड के भीतर उपयोग किए जाते हैं। – ctpenrose

2

एक पुस्तकालय था जो इस सुविधा को प्रदान करता था, लेकिन मैं कहां भूल गया। यह बहिष्कृत क्लोजर-contrib में किया जा सकता है। यह -$> मैक्रो था।

लेकिन आप एक आप देख रहे हैं बनाने के लिए clojure के मुख्य -> macro से एक प्राप्त हो सकता है:

(defmacro -$> 
    ([x] x) 
    ([x form] (if (seq? form) 
       (with-meta (map #(if (= %1 '$) x %1) form) (meta form)) 
       (list form x))) 
    ([x form & more] `(-$> (-$> ~x ~form) [email protected]))) 

और $ का उपयोग सम्मिलन बिंदु इंगित करने के लिए:

user=> (-$> 2 str (identity $) (println $)) 
2 
nil 

तकनीकी तौर पर, आप कर सकते थे एक ही रूप में एकाधिक $ का उपयोग करें। लेकिन यह कार्यान्वयन एक ही रूप में कई बार विस्तार (सादगी के बदले में) से ग्रस्त है।

15

यदि कोई और इस पर आता है, तो उपलब्ध मैक्रोज़ मौजूद होने का एक कारण है, लेकिन एक मनमाने ढंग से प्लेसमेंट कोई नहीं करता है: बाद वाला खराब एपीआई डिज़ाइन का कारण बनता है।

-> मैक्रो पहली स्थिति में तर्क रखता है। यह उन कार्यों के अनुरूप है जो कुछ विषय तर्क पर काम करते हैं, उदाहरण के लिए, conj, assoc

->> मैक्रो अंतिम स्थिति में तर्क रखता है। यह उन कार्यों के अनुरूप है जो अनुक्रमों पर काम करते हैं, उदाहरण के लिए, map, reduce

अपने एपीआई को अच्छी तरह डिज़ाइन करें, और आपको ऐसे मैक्रो की आवश्यकता होने की संभावना कम होगी।

+2

अच्छी तरह से तर्क, एलेक्स। हालांकि कभी-कभी आपको उन कार्यों के माध्यम से थ्रेड डेटा की आवश्यकता होती है जिन्हें आपने डिज़ाइन नहीं किया था। मुझे लगता है कि कोई भी इसके आसपास पाने के लिए हमेशा (# (एफ ए 1% ए 3) का उपयोग कर सकता है। – jbear

+0

'nth' एक कोर फ़ंक्शन का एक अच्छा उदाहरण है जो संग्रह पर काम करता है लेकिन यह अंतिम तर्क के रूप में नहीं बल्कि पहले के रूप में अपेक्षा करता है। –

+0

'nth' भी दूसरों की तरह अनुक्रम नहीं लौटाता है, जिससे नेस्टेड अनुक्रमों में खोदने पर यह अच्छी तरह से काम करता है। मुझे लगता है कि यही कारण है कि यह इस तरह से संरचित है। – deterb

32

अब क्लोजर में एक सामान्यीकृत थ्रेडिंग मैक्रो 1.5 से as-> कहा जाता है। https://twitter.com/borkdude/status/302881431649128448

(as-> "/tmp" x 
     (java.io.File. x) 
     (file-seq x) 
     (filter (memfn isDirectory) x) 
     (count x)) 

सबसे पहले 'एक्स' "/ tmp" और एक फ़ाइल के लिए बाध्य है यह से बाहर कर दिया जाता है:

यह ट्वीट यह कैसे काम करता का एक उदाहरण देता है। 'x' परिणामस्वरूप फ़ाइल को फिर से रिबाउंड किया गया है और 'फ़ाइल-सेक' फ़ंक्शन इत्यादि के माध्यम से रखा गया है।

+0

स्विस तीर लाइब्रेरी मजेदार और सब कुछ है, लेकिन यह 2014 के रूप में शायद सबसे अच्छा जवाब है, क्योंकि यह संस्करण 1.5 के बाद क्लोजर में बनाया गया है। –

+0

गिथब कोड उदाहरण यहां: https://github.com/search?q=as-%3E+extension%3A.clj&type=Code&ref=searchresults –