2010-03-23 16 views
15

मैं क्लोजर में, सामान्य लिस्प वाक्यविन्यास का उपयोग करके लैम्बडा को परिभाषित करने में सक्षम होना चाहता हूं। उदाहरण के लिए:क्लोजर में "लैम्बडा" नामक फ़ंक्शन के रूप में लैम्ब्डा को कैसे कार्यान्वित किया जाए?

#(some-functions-that-refer-to %) 

मेरे मामले में, मैं जानता हूँ कि मैं हमेशा ठीक एक आर्ग होगा, तो शायद यह है कि चीजों को सरल:

(lambda (myarg) 
    (some-functions-that-refer-to myarg)) 

इस में एक ही रूप में परिणाम की जरूरत है। (लेकिन इसे कुछ भी कहा जा सकता है - "मायग" या जो भी हो।)

मुझे संदेह है कि एक व्यावहारिक समाधान "(defmacro lambda ..." है। यदि ऐसा है, तो मुझे आगे बढ़ने का सबसे अच्छा तरीका नहीं है । कैसे सफाई से% करने के लिए आर्ग नाम अनुवाद करने के लिए? और कैसे सही समारोह के साथ समाप्त करने के लिए?

या, वहां अपनी स्वयं की मैक्रो है कि वास्तव में फिर से लागू करता है Clojure के ... लैम्ब्डा लिखने की तुलना में एक सरल समाधान है?

उत्तर

25

#(foo %)(fn [arg] (foo arg)) के लिए केवल पाठक शॉर्टेंड है। #(...) में विस्तारित मैक्रो लिखने का कोई कारण नहीं है। #(...) निर्माण में जीई में विस्तार किया गया है वैसे भी nsyms तुरंत।

user> `#(foo % %1 %2) 
(fn* [user/p1__1877 user/p2__1878] 
    (user/foo user/p1__1877 user/p1__1877 user/p2__1878)) 

क्या तुमने कभी एक मैक्रो अनाम प्रक्रियाएं निर्माण करने के लिए फैलता है लिख रहे हैं, तो आप के रूप में अच्छी सिर्फ उन्हें fn खुद के रूपों का विस्तार हो सकता है। आपके मामले में, आपको शायद fn सीधे उपयोग करना चाहिए और मैक्रोज़ को छोड़ना चाहिए। fn क्लोजर का lambda है।

इस मामले में (fn [] ...) और (lambda() ...) के बीच अंतर यह है कि "एफ एन" टाइप करने के लिए कम "लैम्ब्डा" से है, और fnlambda एक सूची लेता है जबकि इसकी बाइंडिंग के लिए एक वेक्टर लेता है। आप Clojure का उपयोग कर रहे हैं, तो आप क्योंकि वैक्टर हमेशा सभी do रूपों में, बाइंडिंग के संग्रह के लिए उपयोग किया जाता है, यह अंततः आदत हो करना होगा और for और binding में आदि इस के पीछे तर्क मैं यह समझ के रूप में है कि सूचियों है फ़ंक्शन कॉल या मैक्रो कॉल के लिए उपयोग किया जाता है, और वेक्टर उन चीजों के लिए उपयोग किए जाते हैं जो कॉल नहीं हैं (उदाहरण के लिए बाध्य करने के लिए प्रतीकों की सूचियां)। तर्कसंगत रूप से, यह सूचियों के मुकाबले कोड को स्कैन करना आसान बनाता है-सब-द-वे-डाउन। क्लोजर सामान्य लिस्प नहीं है, और यदि आप इसे मजबूर करने की कोशिश करते हैं तो आपको दर्द का अनुभव होगा।

आप सच में, सच यह करने के लिए, बस तुमने कहना चाहता हैं:

user> (defmacro lambda [args & body] 
     `(fn ~(vec args) [email protected])) 
user> ((lambda (x) (println x)) "foo") 
foo 
nil 

यह आपको अन्य बातों के अलावा अपने कार्य पर एक docstring या मेटाडाटा डाल दिया, नहीं देता। मुझे नहीं लगता कि आप इसे वास्तविक क्लोजर कार्यक्रम में उपयोग करना चाहते हैं।

+2

धन्यवाद ब्रायन, यह मैं वास्तव में क्या जरूरत है। मुझे यह कहने में शर्मिंदा है कि मेरे यहां एक अंधेरा स्थान था ... मैं #() चीनी से प्यार करता हूं कि मैं औपचारिक एफएन भूल गया था। अब, मैं वास्तव में वास्तव में वास्तव में मैक्रो दृष्टिकोण का उपयोग करना चाहता हूं, क्योंकि मैं ऐसी परिस्थिति में हूं जहां मुझे "लैम्ब्डा" का उपयोग करने वाले सरल लिस्प कोड को चलाने के लिए मजबूर होना पड़ता है। और आपके द्वारा लिखा गया मैक्रो ठीक वही है जो मुझे चाहिए था। बहुत धन्यवाद! – dirtyvagabond

+0

मजेदार, शुभकामनाएं लगता है। :) –

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