2010-02-20 12 views
5

मैक्रोलेट का उपयोग कर लेक्सिकल क्लोजर जैसे कुछ करने का कोई तरीका है?मैक्रोलेट पर लेक्सिकल बंद?

CL-USER> (combinations nil '(1 2 3) '(4 5 6)) 
((1 4) (1 5) (1 6) (2 4) (2 5) (2 6) (3 4) (3 5) (3 6)) 

मुझे क्या करना चाहते हैं: मुझे क्या करना चाहते हैं निम्नलिखित मैक्रो एक स्थानीय पुनरावर्ती सहायक प्रत्येक संयोजन पर एक फ़ंक्शन को कॉल कर के बजाय एक सूची यह अब में repl परिणामों में मैक्रो बुला करता है के रूप में उत्पन्न कर रहा है एक मैक्रो है जो फ़ंक्शन और किसी भी संख्या में सूचियों और परिणामों को नेस्टेड लूप में लेता है जो प्रत्येक संयोजन पर फ़ंक्शन को कॉल करते हैं। मैं lisp के लिए बहुत नया हूँ, यह पहला मैक्रो है जिसे मैंने 'एनआईएफ' क्लोन से परे लिखा है और इस तरह किसी भी सुझाव की सराहना की जाती है।

मैंने मैक्रो को एक मैक्रो में एक मैक्रोलेट में बदलने की कोशिश की है जो एक फ़ंक्शन लेता है और रेखा '(nreverse (list, item, @ vars))' के साथ प्रतिस्थापित किया जाता है '(func (nreverse (list, item , @ vars))) 'लेकिन मुझे त्रुटियां मिल रही हैं कि func एक अपरिभाषित चर या फ़ंक्शन है।

(defmacro combinations (vars &rest lsts) 
    (with-gensyms (item) 
    `(loop for ,item in ,(car lsts) ,(if (null (cdr lsts)) 'collecting 'nconcing) 
     ,(if (null (cdr lsts)) 
      `(nreverse (list ,item ,@vars)) 
      `(combinations (,item ,@vars) ,@(cdr lsts)))))) 

यह है कि मैं क्या macrolet साथ की कोशिश की और अपरिभाषित समारोह 'समारोह' त्रुटियों मिल गया है:

यह मूल कार्य है।

(defmacro for-all-combonations (func &rest lst) 
     (macrolet ((for-all (vars &rest lsts) 
        (with-gensyms (item) 
         `(loop for ,item in ,(car lsts) ,(if (null (cdr lsts)) 
                  'collecting 'nconcing) 
          ,(if (null (cdr lsts)) 
           `(func (nreverse (list ,item ,@vars))) 
           `(for-all (,item ,@vars) ,@(cdr lsts))))))) 
     (for-all nil lst))) 
+2

क्या आप समझा सकते हैं कि आप इसके लिए मैक्रोज़ का उपयोग क्यों करना चाहते हैं? क्या करना चाहिए (चलो ((एक '((1 2 3) (4 5 6)))) (संयोजन शून्य))? –

+0

इसे वापस करना चाहिए '(((1 2 3)) ((4 5 6))) जो सभी संयोजनों की एक सूची है जो प्रति संयोजन इनपुट की प्रत्येक सूची से तत्व लेता है। मैं इसे मैक्रो के साथ कर रहा हूं क्योंकि यही वह है जो मैं अभी खोज रहा हूं। मैं मैक्रोज़ के बिना ऐसा कर सकता था लेकिन मैं निफ की तुलना में मैक्रो को अधिक जटिल लिखने के लिए अपना हाथ देखना चाहता था। यह मुझे यह जानने का मौका देता है कि क्या किया जा सकता है और क्या नहीं किया जा सकता है, मैं कभी सोचा नहीं होगा कि इस तरह से एक मैक्रोलेट का उपयोग अन्यथा किया जा सकता है। उम्मीद है कि एक बार जब मैं इसे खत्म कर दूंगा तो मैं मैक्रोज़ को बहुत बेहतर समझूंगा। – asm

+2

मुझे नहीं लगता कि यह एक मैक्रो के साथ करने के लिए समझ में आता है। डेटा कोड की गणना करने के लिए मैक्रोज़ हैं, डेटा नहीं। यदि आप डेटा की गणना करना चाहते हैं, तो डेटा मैक्रो विस्तार समय पर होना चाहिए - जो सामान्य नहीं है। –

उत्तर

5

मैक्रो कॉमन लिस्प में नहीं प्रथम श्रेणी वस्तुओं रहे हैं, तो आप वास्तव में एक मैक्रो के रूप में एक शाब्दिक बंद के बराबर नहीं हो सकता। आप एक ऐसा फ़ंक्शन बनाकर एक समान प्रभाव प्राप्त कर सकते हैं जो एक वैध लिस्प प्रोग्राम है जो एक सूची उत्पन्न करता है, और फिर इसे evals।

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

+0

ठीक है, आपने मुझे विश्वास दिलाया। मुझे लगता है कि यह इस अन्वेषण के लिए लाइन का अंत है। – asm

+0

@ एंड्रयू मायर्स - प्रथम श्रेणी के मैक्रोज़ के विचार के कुछ अन्वेषण हुए हैं। सबसे हाल ही में मैंने पॉल ग्राहम को आर्क के विचार पर विचार किया था। मुझे लगता है कि वह इसे ढंकने के लिए समाप्त हो गया क्योंकि यह अनिश्चित लाभ के लिए संकलक को और अधिक जटिल बना दिया। – Zak

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