2012-06-29 30 views
11

मैं मुख्य रूप से एक सी ++ (इस प्रकार एक ओओ/अनिवार्य) प्रोग्रामर हूं और मुझे यह बहुत विचित्र लगता है कि आप एक सशर्त बयान में प्रति मूल्यांकन एक विवरण दे सकते हैं जैसे कि योजना में एक if-statement, एक कार्यात्मक भाषा।क्या सशर्त बयान के शरीर के अंदर कई बयानों की संभावना है?

उदाहरण के लिए:

(let ((arg1 0) (arg2 1)) 
    (if (> arg1 arg2) 
     arg1 
     arg2))) 

गलत उदाहरण:

(let ((arg1 0) (arg2 1)) 
    (if (> arg1 arg2) 
     (arg1 (display "cool")) 
     (arg2 (display "not cool")))) 

मुझे एक प्रकार का एक त्रुटि देता है ": उम्मीद प्रक्रिया, यह देखते हुए: प्रक्रिया आवेदन 2; तर्क गया: #void"

जिसे परिभाषित फ़ंक्शन के शरीर के भीतर अलग-अलग बयानों में कहा गया सशर्त बयान देकर हल किया जा सकता है, सशर्त बयान के शरीर को सीपी रखने के साथ arate बयान हर बार इस प्रकार है:

(if (condition) statement1a statement2a) 
(if (condition) statement1b statement2b) 

और इतने पर ...

यह कह रही है कि यह बहुत व्यावहारिक नहीं है बिना चला जाता है। डुप्लीकेट कोड ओवरहेड का जिक्र नहीं है।

क्या मुझे यहां कुछ याद आ रहा है या वास्तव में कोई अन्य तरीका नहीं है?

उत्तर

13
(let((arg1 0)(arg2 1)) 
    (if (> arg1 arg2) 
     (begin 
     (display arg1) 
     (newline) 
     (display "cool")) 
     (begin 
     (display arg2) 
     (newline) 
     (display "not cool")))) 

जब आप कहते हैं (arg1 (disply "cool")) आप यह कह रहे हैं कि arg1 एक प्रक्षेपण होना चाहिए।

+0

सच है, मुझे यह देखना चाहिए कि फ़ंक्शन कॉल करने के लिए वाक्यविन्यास (function_name args ...) है और एक फ़ंक्शन स्वयं योजना में एक चर हो सकता है। त्रुटि संदेश का उल्लेख नहीं करना ठीक वही बात कहा। एक त्वरित उत्तर के लिए धन्यवाद। –

2

@ राजेशभाट ने एक कथन के साथ शुरू करने का एक अच्छा उदाहरण दिया।

एक और समाधान cond रूप

(let ([arg1 0] [arg2 1]) 
    (cond 
    [(< arg1 0) (display "negative!")] 
    [(> arg1 arg2) (display arg1) (newline) (display "cool")] 
    [else (display arg2) (newline) (display "not cool")])) 

cond रूप में प्रत्येक पंक्ति एक अंतर्निहित begin जो आप वास्तव में अगर आप cond के कार्यान्वयन को देखो देख सकते हैं नहीं है।

(लिंक Chez योजना प्रलेखन के लिए है, (पढ़ सकता है: शायद) नहीं एक ही कार्यान्वयन आप उपयोग कर रहे हैं के रूप में यह स्वामित्व है, हालांकि छोटा Chez (खूबसूरत संस्करण में कोई संकलक) नि: शुल्क है)

http://scheme.com/tspl4/syntax.html#./syntax:s39

संपादित करें: प्रारंभिक रूपों के बारे में महत्वपूर्ण नोट और इसलिए सभी अभिव्यक्तियां शुरू होती हैं।

निम्नलिखित कोड

(+ 2 (begin 3 4 5)) 

7. का मूल्यांकन इसका कारण यह है एक begin फार्म की वापसी मान अपने पिछले अभिव्यक्ति है। प्रारंभ होने पर यह ध्यान में रखना कुछ है। हालांकि, साइड इफेक्ट्स और डिस्प्ले जैसी चीजों का उपयोग करना उन पदों में ठीक काम करेगा जहां 3 और 4 हैं।

+0

धन्यवाद: मैं इसे ध्यान में रखूंगा। अगर + शुरू होता है और लगता है कि एक ही काम कर रहा है, तो मैं नियमित रूप से दोनों का उपयोग करूँगा जबकि मैं खुद को योजना पढ़ रहा हूं। –

6

एक चीज जो आपको याद आ रही है वह यह है कि योजना में "कथन" जैसी कोई चीज़ नहीं है। सबकुछ एक अभिव्यक्ति है और जिन चीजों पर आप विचार कर सकते हैं वे भी एक मूल्य वापस कर सकते हैं। यह if पर लागू होता है, जिसे आम तौर पर एक मान वापस करने के लिए उपयोग किया जाता है (उदा।, (if (tea-drinker?) 'tea 'coffee)।सी ++ के विपरीत, सशर्त के अधिकांश उपयोग एक परिवर्तनीय या प्रिंटिंग मानों को म्यूट करने के लिए नहीं होंगे। इससे if खंड में एकाधिक अभिव्यक्तियों की आवश्यकता कम हो जाती है।

हालांकि, जैसा कि रॉस और राजेश ने इंगित किया है, आप cond (अनुशंसित) का उपयोग कर सकते हैं या अपने if खंडों में begin का उपयोग कर सकते हैं। ध्यान दें कि यदि आपके पास सशर्त में कई साइड इफेक्टिंग कंप्यूटेशंस हैं, तो हो सकता है कि आप योजना का उपयोग मूर्खतापूर्वक नहीं कर रहे हों।

+0

इससे मुझे लगता है: मुझे शायद योजना में कार्यों को लागू करने के लिए एक उचित तरीका तलाशना चाहिए। यह सी-आधारित भाषाओं की तुलना में प्रोग्रामिंग के लिए एक पूरी तरह से अलग दृष्टिकोण है।दरअसल, यहां तक ​​कि रिकर्सन का उपयोग सी ++ (स्टैक ओवरफ्लो, विडंबनात्मक रूप से होने की संभावना) में निराश होता है, जबकि योजना और लिस्प-आधारित भाषाओं में यह जीवन का एक तरीका है। ओह और रास्ते से धन्यवाद। –

+1

क्या आपने देखा [प्रोग्राम कैसे डिजाइन करें] (http://www.htdp.org/)? यह एक पाठ्यपुस्तक है जो आपको एक कार्यात्मक शैली में कार्यों को डिजाइन करने की प्रक्रिया के माध्यम से मार्गदर्शन करती है (हालांकि अंत में यह उत्परिवर्तन का उपयोग करने के बारे में भी बात करती है)। पर्याप्त सुधार के साथ एक कार्य प्रगति [2 संस्करण] (http://www.ccs.neu.edu/home/matthias/HtDP2e/index.html) भी है। –

+0

इसके अलावा, यह स्पष्ट करने के लिए कि 'शुरूआत' क्या कर रही है, अगर मैं इसे सही ढंग से समझता हूं, तो यह सिर्फ लम्दाबा बनाता है और तुरंत इसे लागू करता है। यही है, '(एक दो तीन शुरू करें) 'जैसा ही है ((लैम्ब्डा() एक दो तीन))। – d11wtq

1

आप पहले से ही "आंतरिक" प्रक्रिया में एक सतत प्रक्रिया का उपयोग कर रहे हैं, यही कारण है कि इस परिभाषा का उपयोग कर नामित उपयोग नहीं

(define (fact n) 
    (let inner ((counter 1) (result 1)) 
    (if (> counter n) 
     result 
     (inner (+ counter 1) (* result counter))))) 

जाने के बाद से इस प्रक्रिया का राज्य सिर्फ 2 चर के साथ निर्धारित किया जा सकता, यह उस स्मृति का उपयोग नहीं करेगा।

उदाहरण के लिए

(वास्तव 6) इस

(inner 1 1) 
(inner 2 1) 
(inner 3 2) 
(inner 4 6) 
(inner 5 24) 
(inner 6 120) 
(inner 7 720) 
720 

की तरह की जाती है यहाँ एक ही प्रक्रिया के letrec संस्करण है:

(define (fact n) 
    (letrec ((inner 
      (lambda (counter result) 
       (if (> counter n) 
        result 
        (inner (+ counter 1) (* result counter)))))) 
    (inner 1 1))) 
+0

मैंने अभी तक तीन रूपों को देखा है: चलो, चलो * और letrec। मुझे अभी तक यह देखने के लिए नहीं है कि कैसे तरल पदार्थ दें और नाम दें- काम करें। आपका कोड स्पष्ट रूप से मेरी तुलना में अधिक कॉम्पैक्ट है, लेकिन क्या आप सुनिश्चित हैं कि स्मृति लागत भी कम है? मेरा फ़ंक्शन 3 चर के साथ-साथ उत्परिवर्तन का उपयोग करता है। –

+0

आपके विश्वास के लिए letrec संस्करण जोड़ने के लिए संपादित किया गया। यह बिल्कुल वही काम करता है। एक पुनरावर्ती प्रक्रिया के लिए बहुत सारी मेमोरी की आवश्यकता होती है क्योंकि इसे पिछले राज्यों को याद रखना होता है। ऊपर दिए गए कार्यों को रिकर्सिव हो सकता है, लेकिन ** प्रक्रिया पुनरावर्तक ** है। इसे पिछले राज्यों की स्मृति की आवश्यकता नहीं है। –

+0

मैं देखता हूं, मुझे नहीं लगता था कि यह पुनरावृत्त था। लेकिन अब करीब निरीक्षण पर मैं देख सकता हूं कि सेट की आवश्यकता को छोड़कर, इसके कार्य को आंतरिक कार्य के दूसरे तर्क में हो रहा है! (असाइनमेंट) कथन। एक सुरुचिपूर्ण विकल्प प्रदान करने के लिए धन्यवाद। –

1

आप योजना के वाक्य रचना द्वारा प्रतिबंधित महसूस हैं, तो आप कभी भी बदल सकते एक मैक्रो परिभाषित करके वाक्यविन्यास। एक मैक्रो लैम्ब्डा की तरह होता है, सिवाय इसके कि यह संकलन-समय (जैसे सी ++ टेम्पलेट) पर कोड उत्पन्न करता है और इसके तर्कों को मैक्रो लागू होने से पहले मूल्यांकन नहीं किया जाता है।

आप सिंटैक्स का उपयोग करने के लिए आसानी से एक मैक्रो बना सकते हैं जिसका मतलब सामान्यतः प्रक्रिया-अनुप्रयोग, (arg1 "cool") जैसा है, जिसका मतलब है "प्रत्येक आइटम के बाद एक नई लाइन के साथ कोष्ठक के अंदर सबकुछ प्रदर्शित करें"। (इसका मतलब यह होगा कि केवल मैक्रो, निश्चित रूप से अंदर।) इस तरह:

(define-syntax print-if 
    (syntax-rules() 
    [(_ c (true-print ...) (false-print ...)) 
     (if c 
      (display-with-newlines true-print ...) 
      (display-with-newlines false-print ...))])) 

(define-syntax display-with-newlines 
    (syntax-rules() 
    [(_ e) 
     (begin (display e) (newline))] 
    [(_ e0 e* ...) 
     (begin (display-with-newlines e0) (display-with-newlines e* ...)) ])) 

(let ([arg1 0] [arg2 1]) 
    (print-if (> arg1 arg2) 
      (arg1 "cool") 
      (arg2 "not cool"))) 

आउटपुट:

1 
not cool 

चिंता मत करो अगर आप समझ में नहीं आता कि कैसे मैक्रो परिभाषाओं सही काम अभी व। यदि आप सी ++ को महारत हासिल करने के बाद ही योजना की कोशिश कर रहे हैं, तो इसमें कोई संदेह नहीं है कि आप बहुत निराशा का अनुभव कर रहे हैं। वास्तव में आपके पास बिजली और लचीलापन योजना की तरह एक झलक दिखनी चाहिए।

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

और यदि आप चाहें तो किसी को भी दुष्प्रभावों का उपयोग करने से हतोत्साहित न करें। योजना की महिमा यह है कि आप जो भी आप चाहते हैं कर सकते हैं।

+0

कूल, धन्यवाद! मैं इसके साथ सभी तरह की पागल सामान करने में सक्षम होना चाहिए, बशर्ते मैं मास्टर स्कीम मैक्रो सिस्टम प्रदान करता हूं। –