2012-10-02 21 views
13

मैं clojure के लिए नया हूँ, और मैं की तरह लिखा अनाम प्रक्रियाएं देखा है:क्लोजर में अज्ञात कार्यों के लिए एफएन और # वाक्यविन्यास के बीच कोई अंतर है?

(fn [x] (* x x)) 

और यह भी पसंद:

#(* % %) 

जाहिर है, दूसरा अधिक संक्षिप्त है। क्या कोई प्रासंगिक अंतर है? क्या प्रत्येक अज्ञात फ़ंक्शन किसी भी शैली में प्रदर्शित किया जा सकता है? क्या एक और मूर्खतापूर्ण है?

इस प्रश्न से संबंधित, मैं यह निर्धारित करने में असमर्थ था कि (fn [x] [x x]) को बाद वाले वाक्यविन्यास में कैसे परिवर्तित किया जाए। मैं दस्तावेज के लिए एक सूचक की सराहना करता हूं जो इस स्थिति को स्पष्ट करता है।

+1

#() का कोई निहित नहीं है। (एफएन [] ...) करता है। – Bill

+0

@ बिल की टिप्पणी पर विस्तार करने के लिए: http://stackoverflow.com/questions/12534287/why-does-this-anonymous-function-starting-with-println-result-in-a-nullpointerex – noahlz

उत्तर

20

सबसे महत्वपूर्ण अंतर हैं:

  • (fn ...) नेस्ट किया जा सकता है, #() नहीं
  • आप अपने मानकों को (fn [x y] ..) या इसी तरह, के साथ बेहतर नहीं बल्कि %, %2, %3 आदि
  • का उपयोग करने से नाम कर सकते हैं कर सकते हैं आप रिकर्सिव उपयोग के लिए (fn ...) के साथ फ़ंक्शन का नाम दे सकते हैं, उदाहरण के लिए (fn fib [n] (if (<= n 1) 1 (+ (fib (- n 1)) (fib (- n 2)))))
  • #() के बाद से कोड जनरेशन/मैनिपुलेशन (fn [...] ...) करना आसान है क्योंकि नियमित क्लोजर फॉर्म की बजाय एक पाठक मैक्रो है।
  • #() अधिक संक्षिप्त है। लेकिन यह है कि अगर एक प्रमुख विचार है, तो आप शायद अपने प्राथमिकताओं गलत :-)

निजी तौर पर मेरी सलाह होगा:

  • केवल बहुत ही कम इनलाइन के लिए
  • उपयोग #() सबसे परिस्थितियों में (fn [...] ...) पसंद करते हैं कार्य, उदाहरण के लिए (map #(+ 2 %) (range 10))
  • यह भी मान लें कि स्पष्ट रूप से उन्हें लिखने के बजाय उच्च-आदेश कार्यों के माध्यम से अनाम कार्यों को उत्पन्न करना बेहतर हो सकता है। (comp func1 func2) या (partial func param1 param2) आदि
+1

उल्लेख करने के लायक एक और सीमा (I पता नहीं था कि क्या मैं आपकी प्रतिक्रिया संपादित कर सकता/सकती हूं) यह है कि 'एफएन' आपको अपने फ़ंक्शन का नाम देने की अनुमति देता है, ताकि इन्हें शरीर के भीतर संदर्भित किया जा सके, जैसे: '(def तथ्य (fn f [x] (अगर (= 1 एक्स) 1 (* एक्स (एफ (डीसी एक्स)))))) –

+0

वास्तव में 'comp' और 'आंशिक' सुझावों की सराहना करते हैं। मुझे आश्चर्य हुआ कि क्या वे मौजूद थे, उन्होंने हास्केल में उनकी सराहना की। –

2

docs से, मुझे लगता है कि यह है कि इन सबसे अधिक प्रासंगिक अंतर हैं:

मुहावरेदार प्रयोग किया जाता बहुत ही कम एक बंद मानचित्रण/फिल्टर FNS और पसंद के लिए किया जाएगा।

#() रूपों को घोंसला नहीं किया जा सकता है।

एक और बात यह है कि यदि आपको नामित पैरामीटर की आवश्यकता है, तो एफएन एक बेहतर विकल्प है। #() के लिए आप% या, एक पैरामीटर के लिए,% 1,% 2 और इसी तरह कुछ (% &) के लिए उपयोग करेंगे।

4

एक और तो जवाब (Common programming mistakes for Clojure developers to avoid) कहा गया है कि #([% %]) (कोष्ठकों ध्यान दें) fn [%] ([% %]) के लिए विस्तारित है, जो एक ArityException कारण बनता है।

आप इस सीमा को हल करने के लिए #(vector % %) कर सकते हैं।

+0

आपको यह नहीं बता सकता कि इस वजह से मैंने कितना समय बर्बाद कर दिया है। – Bill

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