2009-02-08 9 views
14

क्या यह 1 9 50 के दशक से कुछ ऐतिहासिक क्रॉफ्ट छोड़ दिया गया है या क्या कुछ कारण वाक्य रचनात्मक रूप से क्यों हैं (यदि) रूपों के बहु अभिव्यक्ति निकायों (प्रज्ञान) की आवश्यकता है? क्यों आप के साथ की तरह कोष्ठकों का एक सेट में एक से अधिक भाव रैप नहीं कर सकते हैं (है): ​​आम लिस्प में, (अगर) बयानों के बहु-अभिव्यक्ति निकायों की आवश्यकता क्यों होती है (प्रज्ञान)?

(if some-cond 
    ((exp1) (exp2) (exp3)) ; multi exp "then" 
    (exp4)) ; single exp "else" 

ऐसा प्रतीत होता है कि यह शरीर के प्रत्येक परीक्षण करने के लिए पहले देखने के लिए अगर यह एक सूची है एक मैक्रो लिखने के लिए तुच्छ हो सकता है और तो यदि यह है, यदि इसका पहला तत्व भी एक सूची है (और इस प्रकार एक फ़ंक्शन आमंत्रण नहीं है) और उसके बाद अपने उपमहाद्वीपों को तदनुसार (प्रजनन) के अंदर लपेटने के लिए।

उत्तर

3

विस्तारित संस्करण के लिए पहले से ही मैक्रोज़ हैं। यह पुस्तक वास्तव में अच्छी है: http://www.gigamonkeys.com/book/ आपका उत्तर इस अध्याय में है: http://www.gigamonkeys.com/book/macros-standard-control-constructs.html

मानक मैक्रोज़ कब और जब तक होते हैं।

+0

लेकिन (कब) और (जब तक) अन्य शाखाएं नहीं हैं। –

4

सभी अभिव्यक्तियाँ सूचीबद्ध नहीं हैं। (let ((a 42)) (if some-cond (a b c) (d e f))) के लिए आपको पता नहीं होगा कि (a b c) को फ़ंक्शन a या एक निहित प्रोजेक्ट के रूप में कॉल के रूप में व्याख्या किया जाना चाहिए।

+0

नहीं, मेरे विवरण के अनुसार (बी बी) एक सूची है और इसका पहला तत्व भी एक सूची नहीं है, यह एक फ़ंक्शन आमंत्रण है और उसे प्रज्ञान की आवश्यकता नहीं है। –

1

लिस्प में, कोष्ठक फ़ंक्शन एप्लिकेशन इंगित करते हैं, समूहबद्ध नहीं करते हैं। आपकी अभिव्यक्ति का क्या अर्थ होगा यदि exp1 एक ऐसा फ़ंक्शन था जो फ़ंक्शन लौटाता था? क्या इसे (exp2) (exp3) के तर्कों के साथ बुलाया जाएगा या नहीं?

+0

यदि पहला उप अभिव्यक्ति भी एक सूची थी तो उन सभी को लपेटा जाएगा (प्रज्ञान) –

3

जब आपके पास कोई और 'शाखा' नहीं है, मानक मैक्रोज़ when और unless सहायता। अन्यथा यदि आपके पास किसी भी शाखा में एकाधिक अभिव्यक्तियां हैं तो cond का उपयोग करना बेहतर है।

6

क्या कुछ कारण वाक्य रचनात्मक रूप से क्यों हैं (यदि) रूपों के बहु अभिव्यक्ति निकायों (प्रज्ञान) की आवश्यकता है?

उत्तर "हां" है, हालांकि शायद आप जिस कारण से उम्मीद कर रहे हैं उसके लिए नहीं। क्योंकि आम लिस्प (योजना और अन्य लिस्प्स के विपरीत) funcall की आवश्यकता है, आपका प्रस्ताव संदिग्ध नहीं है। यहां तक ​​कि अगर यह संदिग्ध था, तब तक जब तक आपके उपयोगकर्ता जानते हैं कि ब्रांड्स progn का संकेत देते हैं, यह काम करेगा।

हालांकि, भाषा में कोई अन्य निर्माण * वैकल्पिक एकल/डबल कोष्ठक नहीं है। निर्माण के बहुत सारे progn एस निहित हैं, लेकिन उनके मूलभूत वाक्यविन्यास हमेशा एक ही हैं। भले ही अपने प्रस्ताव अस्पष्ट नहीं है

(cond test1 exp1 (test2 body2) t exp3) 

तो,,:

उदाहरण के लिए, cond प्रत्येक शाखा के लिए एक अंतर्निहित progn है:

(cond (test1 body1) (test2 body2) ...) 

आप परिवर्तन नहीं कर सकते आगे पीछे यह शेष भाषा के वाक्यविन्यास फिट नहीं है। तथापि! जैसा कि आपने कहा था, मैक्रो लागू करने के लिए तुच्छ है। आपको इसे स्वयं करना चाहिए और देखें कि यह अच्छी तरह से काम करता है या नहीं। मैं आसानी से गलत हो सकता था; मैं काफी पक्षपातपूर्ण हूं क्योंकि लगभग सभी मेरे लिस्पिंग योजना में हैं।

* case को छोड़कर। HMF। अब मुझे लगता है कि कुछ भी हो सकते हैं।

11

आम लिस्प सही नहीं है क्योंकि यह सही है, यह सही है क्योंकि यह सही है।

पूरी भाषा 25 special operators पर बनाई गई है; if उनमें से एक है, progn दूसरा है।

if केवल एक शर्त का परीक्षण करने का मूल तंत्र प्रदान करता है, फिर एक या दूसरे कोड पते पर कूदता है। progn कई चीजें करने और अंतिम के मूल्य को वापस करने का मूल तंत्र प्रदान करता है।

भाषा मानक में कई मैक्रोज़ हैं जो इस पर निर्माण करते हैं - उदा। when, unless, cond, case

यदि आप चाहते हैं, आप क्या कल्पना की तरह कुछ बनाने के लिए कई विकल्प हैं: एक के लिए, आप एक ifm मैक्रो को तात्कालिक और बाकी-खंड के रूप में की उम्मीद निहित progn रों लिख सकता है, या आप इसे लिख सकता है जैसे आपने कहा , ताकि यह इरादा का पता लगा सके, या आप progn के लिए वाक्य रचनात्मक चीनी जोड़ने के लिए एक पढ़ा मैक्रो भी लिख सकते हैं।

17

कॉमन लिस्प में, इस कोड:

(if t 
    ((lambda (x) (+ x 5)) 10) 
    20) 

15. वापस आ जाएगी अपने प्रस्ताव के साथ, मुझे लगता है कि यह देखना होगा कि सच खंड एक सूची है, और स्वचालित रूप से इसे करने के लिए कनवर्ट:

(if t 
    (progn (lambda (x) (+ x 5)) 10) 
    20) 

जो 10 लौटाएगा। क्या यह सही है?

मुझे यकीन नहीं है कि सीएल में "सूची" और "फ़ंक्शन आमंत्रण" के बीच अंतर करने के लिए यह "तुच्छ" है। क्या आप इस बदलाव को गैर-पीछे-संगत होने का इरादा रखते हैं? (नई और रोचक लिस्प बोलीयां हमेशा शांत होती हैं, लेकिन फिर यह आम लिस्प नहीं है।) या क्या आप दिमाग में जो कुछ भी रखते हैं उसका एक उदाहरण दे सकते हैं?

4

क्योंकि IF (< - HyperSpec लिंक) के लिए वाक्य रचना के रूप में परिभाषित किया गया है:

if test-form then-form [else-form] => result* 

कोई शुरू कर रहे हैं या अंत मार्करों। एक फिर-फार्म है और फिर नहीं - फॉर्म *। प्रोग्न फॉर्म के अनुक्रम को परिभाषित करने के लिए एक तंत्र है, जहां फॉर्म बाएं से दाएं से निष्पादित किए जाते हैं और अंतिम रूप के मान वापस लौटाए जाते हैं।

यह इस तरह परिभाषित किया जा सकता था: स्थिति:

my-if test-form (then-form*) [(else-form*)] => result* 

(defmacro my-if (test then &optional else) 
    (assert (and (listp then) (listp else)) (then else)) 
    `(if ,test (progn ,@then) (progn ,@else))) 

(my-if (> (random 10) 5) 
     ((print "high") 
     :high) 
     ((print "low") 
     :low)) 

ठीक है, वहाँ पहले से ही एक निर्माण कि कई रूपों का समर्थन करता है है।

(cond ((> (random 10) 5) 
     (print "high") 
     :high) 
     (t 
     (print "low") 
     :low)) 

सामान्य शैली को COND का उपयोग करना है जब एकाधिक विकल्पों की कोशिश की जानी चाहिए और जब कई और अन्य रूप हैं। IF का उपयोग तब किया जाता है जब केवल एक परीक्षण होता है और फिर एक और दूसरा रूप होता है। अन्य मामलों के लिए कब और अनल्य है। कब और अनल्य समर्थन केवल एक या फिर फॉर्म (कोई और रूप नहीं)।

मुझे लगता है कि कम से कम एक सशर्त रूप (यदि इस मामले में) है तो यह अच्छा है कि ब्रांड्स के अतिरिक्त परतों के बिना आता है। लेखन

(if (> (random 10) 5) 
    (progn 
     (print "high") 
     :high) 
    (progn 
     (print "low") 
     :low)) 

तब भुगतान करने के लिए एक छोटी सी कीमत है। या तो अतिरिक्त प्रोग्न लिखें या COND संस्करण पर स्विच करें। यदि आपका कोड वास्तव में कई से IF से लाभान्वित होगा और अन्य रूपों के साथ, तो बस उस मैक्रो को लिखें (ऊपर देखें)। लिस्प में यह है, ताकि आप अपना खुद का भाषा डिजाइनर बन सकें। मैक्रो शुरू करने के बारे में सोचना महत्वपूर्ण है: क्या मेरा मैक्रो सही है? क्या यह त्रुटियों की जांच करता है? यह इसके लायक है? क्या यह पठनीय है (दूसरों के लिए?)?

3

ध्यान दें कि "{} भाषाओं" (सी, सी ++, जावा ...) में आपके पास ब्रेसिज़ में कंपाउंड स्टेटमेंट के रूप में एक PROGN है।

तो ध्यान दें कि इन equivalences/उपमा:

(if antecedent consequent alternative) 
if (antecedent) consequent; else alternative; 

(if antecedent (progn consequent1 consequent2) alternative) 
if (antecedent) { consequent1; consequent2; } else alternative; 

PROGN ऑपरेटर (और उसके चचेरे भाई) लिस्प के "ब्रेसिज़" कर रहे हैं। लिस्प में कोष्ठक इसकी "ब्रेसिज़" नहीं हैं!

अब पर्ल पर विचार करें। पर्ल में पूरी तरह से ब्रेस्ड if है। यह लिस्प भी में किया जा सकता है:

(if antecedent (consequent1 consequent2 ...) (alternative1 alternative2 ...)) 

उदा .:

(if (< foo 0) 
    ((format t "foo is less than zero") 
    (- foo)) 
    ((format t "foo is not less than zero") 
    foo)) 

मैं इस के साथ रह सकता है, मुझे लगता है, लेकिन कुछ लोगों को अतिरिक्त कोष्ठकों के बारे में शिकायत करेंगे, विशेष रूप से साधारण मामलों में।

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