2012-04-17 13 views
9
(do ((n 0 (1+ n)) 
    (cur 0 next) 
    (next 1 (+ cur next))) 
    ((= 10 n) cur))) 

यह कीवर्ड के बारे में लिस्प पाठ्यपुस्तक से एक उदाहरण है करना "do"कॉमन लिस्प को समझना मैक्रो वाक्य रचना

"do" बुनियादी टेम्पलेट है:

(do (variable-definitions*) 
    (end-test-form result-form*) 
statement*) 

लेकिन, इस उदाहरण के लिए, यह मुझे स्पष्ट नहीं है कि कौन सा हिस्सा है। और साथ ही, ते मध्यम 2 लाइनें क्या करती हैं?

धन्यवाद!

+3

AFAIR, "do" एक मैक्रो है। – zvrba

उत्तर

8

आपका अच्छा खरोज स्पष्ट रूप से पैदावार से पता चलता है जो हिस्सा है जो करने के लिए योग होगा:

(do ((n 0 (1+ n)) 
    ^(cur 0 next) 
    |(next 1 (+ cur next))) 
    | 
    +-- first argument of do 

    ((= 10 n) cur))) 
    ^
    | 
    +-- start of second argument of do 

देखो, वे अच्छी तरह से लाइन अप, और भीतरी सामग्री इंडेंट है:

((n 0 (1+ n)) 
    (cur 0 next) 
    (next 1 (+ cur next))) 
    ^
    | 
    +- inner material of argument: three forms which are 
     indented by 1 character and aligned together. 

आपका do वहाँ एक तीसरा तर्क नहीं है: वहाँ के कोई शरीर है टेटमेंट्स (खाली पाश)।

23
(do ((n 0 (1+ n)) ;declares n, initially 0, n+1 each subsequent iteration) 
    (cur 0 next) ;declares cur, initially 0, then old value of next 
    (next 1 (+ cur next))) ;declares next, initially 1, then the sum of (the old) cur and next 
    ((= 10 n) ;end condition (ends when n = 10) 
    cur) ; return value 
    ;empty body 
) 

ग की तरह कोड

for(n=0, cur=0, next=1 ; 
    !(n == 10) ; 
    n=old_n+1, cur=old_next, next = old_cur + old_next) 
{ 
    //do nothing 
    old_n = n; 
    old_cur = cur; 
    old_next = next; 
} 
return cur; 

में अनुवाद संयोग से आपको लगता है कि इस कोड को 10 वीं फाइबोनैचि संख्या


वैकल्पिक EBNF/औपचारिक वाक्य रचना देता है देखने के लिए सक्षम होना चाहिए:

के अनुसार वाक्यविन्यासहै:

(do ({var | (var [init-form [step-form]])}*) 
    (end-test-form result-form*) 
    declaration* 
    {tag | statement}*) 

को समझना इस Hyperspec

+1

समानांतर असाइनमेंट अनुकरण करने के लिए 'old_' वर्णों का उपयोग करके सी अनुवाद दिखाने का शानदार विचार!बस साफ-सुथरा करने के लिए: आपका लिस्प कोड गलत गठबंधन है और इसमें एक अतिरिक्त समापन संश्लेषण है; आपके सी कोड में समाप्ति अर्धविराम गुम है। :) –

+0

इस अनुवाद को देखते हुए, क्या यह कहना सही है कि क्या मैक्रो कार्यात्मक प्रोग्रामिंग की बजाय अनिवार्य प्रोग्रामिंग की तरह है? –

+1

@hyh हाँ और नहीं --- सामान्य लिस्प बहु-प्रतिमान है, और यह एक पुनरावृत्ति निर्माण है जो अद्यतन चर, जो निश्चित रूप से अनिवार्य है। हालांकि यह फॉर्म एक मान देता है, इसलिए आप इस लूप को रिटर्न वैल्यू के रूप में या कथन में एक शर्त के रूप में उपयोग कर सकते हैं (यानी '(अगर (> (यह-फाइब-लूप) 10)' gt-10 'lte-10) ') जो अधिक कार्यात्मक – tobyodavies

0
(do ((n 0 (1+ n)) 
    (cur 0 next) 
    (next 1 (+ cur next))) 
    ((= 10 n) cur)) 

की EBNF का ज्ञान और बड़ा हिस्सा की आवश्यकता कर 3 हिस्सा है।

  1. चर
  2. समाप्त हालत
  3. शरीर

इस विशिष्ट उदाहरण में कोई शरीर नहीं है। सभी वास्तविक काम 1. और 2. द्वारा किए गए हैं। सबसे पहले यह 3 वर्र्स सेट करें और प्रारंभिक मान और चरण फ़ॉर्म दें। जैसे n 0 पर सेट और प्रत्येक यात्रा के दौरान यह कदम आगे: (1+ n) जो भी वृद्धि होगी n

हालत समाप्त ((= n 10) cur) है: जब n बराबर 10 फिर इस do अभिव्यक्ति की पूरी वापसी मान के रूप में cur लौट आते हैं।

इस do उदाहरण में इन सभी, कम्बाइन यह 1 से 10 जो 55

+2

है, यह 'परिणाम-फॉर्म-एन' नहीं है 'action-n' भी आपका दूसरा कोड ब्लॉक बुरी तरह से इंडेंट है। – tobyodavies

+1

आपने वहां कई कोष्ठक याद किए हैं। इसके अलावा, यह अनुक्रम '(cur, next) = (0,1) (1,1) (1,2) (2,3) (3,5) (5,8) (8,13) की गणना करता है .. । फिबोनाची संख्याओं का, केवल आंशिक योग नहीं। –

+0

@tobyodavies आप सही हैं। मेरी गलती। – juanitofatas

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