मैं अनुभाग में अपने कोड का विश्लेषण अपने कोड का विश्लेषण करना । इससे पहले मैं बोनस सामग्री के कुछ मजेदार खंड प्रस्तुत करता हूं।
वन लाइनर वन लेटर 1
say e; # 2.718281828459045
e
Raku में कंप्यूटिंग पर डेमियन कॉनवे के असाधारण लेख को देखने के लिए उपरोक्त लिंक पर क्लिक करें ।
लेख बहुत मजेदार है (आखिरकार, यह डेमियन है)। यह कंप्यूटिंग के बारे में बहुत समझने योग्य चर्चा है e
। और यह राकू के बाइकार्बोनेट पुनर्जन्म का एक श्रद्धांजलि है जो लारियल वाल द्वारा जासूसी की गई TIMTOWTDI दर्शन का पुनर्जन्म है। 3
क्षुधावर्धक के रूप में, यहाँ लेख के माध्यम से लगभग आधे रास्ते से एक उद्धरण है:
यह देखते हुए कि ये कुशल विधियाँ सभी तरह से काम करती हैं- संक्षेप में (प्रारंभिक उपसमुच्चय) शब्दों की एक अनंत श्रृंखला है - शायद यह बेहतर होगा यदि हमारे पास ऐसा करने के लिए कोई फ़ंक्शन हो। और यह निश्चित रूप से बेहतर होगा यदि फ़ंक्शन अपने आप से काम कर सकता है, तो श्रृंखला के उस प्रारंभिक उपसमुच्चय का वास्तव में कितना सटीक उत्तर देने के लिए शामिल करने की आवश्यकता है ... बजाय मैन्युअल रूप से परिणाम के माध्यम से कंघी करने की आवश्यकता के कई परीक्षणों की खोज करने के लिए।
और, इतनी बार Raku में, यह आश्चर्यजनक रूप से आसान बनाने के लिए बस हमें क्या चाहिए:
sub Σ (Unary $block --> Numeric) {
(0..∞).map($block).produce(&[+]).&converge
}
अपने कोड का विश्लेषण
यहां पहली पंक्ति है, श्रृंखला उत्पन्न करना:
my @e = 1, { state $a=1; 1 / ($_ * $a++) } ... *;
बंद ( { code goes here }
) एक शब्द की गणना करता है। एक क्लोजर में एक हस्ताक्षर है, या तो निहित या स्पष्ट है, यह निर्धारित करता है कि यह कितने तर्क स्वीकार करेगा। इस मामले में कोई स्पष्ट हस्ताक्षर नहीं है। $_
( "विषय" चर ) के उपयोग से एक निहित हस्ताक्षर होता है जिसके लिए एक तर्क की आवश्यकता होती है $_
।
अनुक्रम ऑपरेटर ( ...
) बार-बार अपने बाईं ओर बंद होने को बुलाता है, पिछले शब्द को क्लोजर के तर्क के रूप में पारित करता है, आलसी रूप से अपने दाईं ओर समापन बिंदु तक शर्तों की एक श्रृंखला का निर्माण करने के लिए , जो इस मामले में उर्फ अनन्तता के *
लिए आशुलिपि है Inf
।
बंद करने के लिए पहली कॉल में विषय है 1
। इसलिए क्लोजर गणना करता है और 1 / (1 * 1)
श्रृंखला में पहले दो शब्दों की उपज देता है 1, 1/1
।
दूसरी कॉल में विषय पिछले एक का मूल्य है 1/1
, अर्थात 1
फिर से। तो समापन गणना और रिटर्न 1 / (1 * 2)
, श्रृंखला को विस्तारित करता है 1, 1/1, 1/2
। यह सब अच्छा लग रहा है।
अगला क्लोजर कम्प्यूट करता है 1 / (1/2 * 3)
जो है 0.666667
। वह पद होना चाहिए 1 / (1 * 2 * 3)
। उफ़।
अपने कोड को सूत्र से मिलान करना
आपका कोड सूत्र से मेल खाने वाला है:
इस सूत्र में, प्रत्येक पद की गणना श्रृंखला में उसकी स्थिति के आधार पर की जाती है । कश्मीर वें श्रृंखला (जहां में अवधि कश्मीर = 0 पहले के लिए 1
) केवल भाज्य है कश्मीर की पारस्परिक।
(तो यह कोई लेना देना नहीं मिला है मूल्य पहले कार्यकाल के। इस प्रकार $_
, जो प्राप्त करता है मूल्य पहले कार्यकाल के, बंद में नहीं किया जाना चाहिए।)
आइए एक फैक्टोरियल पोस्टफ़िक्स ऑपरेटर बनाएं:
sub postfix:<!> (\k) { [×] 1 .. k }
( ×
एक इन्फिक्स मल्टीप्लोरेशन ऑपरेटर है, जो कि एक सामान्य ASCII इन्फिनिटी का यूनिकोड उर्फ देख रहा है *
।)
इसके लिए आशुलिपि है:
sub postfix:<!> (\k) { 1 × 2 × 3 × .... × k }
(मैंने आवश्यकतानुसार कई शब्दों को जोड़ने या घटाने के विचार को दर्शाने के लिए ब्रेसिज़ के अंदर छद्म मेटासाइनेटिक संकेतन का उपयोग किया है।
अधिक आम तौर पर, op
एक अभिव्यक्ति की शुरुआत में वर्ग कोष्ठक में एक infix ऑपरेटर डालने से एक समग्र उपसर्ग ऑपरेटर बनता है जो इसके बराबर होता है reduce with => &[op],
। अधिक जानकारी के लिए रिडक्शन मेटाऑपरेटर देखें ।
अब हम नए फैक्टरियल पोस्टफिक्स ऑपरेटर का उपयोग करने के लिए बंद को फिर से लिख सकते हैं:
my @e = 1, { state $a=1; 1 / $a++! } ... *;
बिंगो। यह सही श्रृंखला का निर्माण करता है।
... जब तक ऐसा नहीं होता, एक अलग कारण से। अगली समस्या संख्यात्मक सटीकता है। लेकिन इससे अगले भाग में बात करते हैं।
आपके कोड से प्राप्त एक लाइनर
हो सकता है कि तीन पंक्तियों को एक में संकुचित करें:
say [+] .[^10] given 1, { 1 / [×] 1 .. ++$ } ... Inf
.[^10]
उस विषय पर लागू होता है, जो इसके द्वारा निर्धारित होता है given
। (इसके ^10
लिए शॉर्टहैंड है 0..9
, इसलिए उपरोक्त कोड श्रृंखला में पहले दस शब्दों के योग की गणना करता है।)
मैंने $a
क्लोजर कंप्यूटिंग से अगले कार्यकाल को समाप्त कर दिया है । एक अकेला एक $
समान है (state $)
, जो एक अनौपचारिक अवस्था है। मैं इसे एक पूर्व वेतन वृद्धि के बजाय बाद वेतन वृद्धि एक ही प्रभाव को प्राप्त करने के रूप में आप आरंभ द्वारा किया बनाया $a
करने के लिए 1
।
अब हम अंतिम (बड़ी!) समस्या से बचे हैं, आपके द्वारा नीचे टिप्पणी में बताया गया है।
बशर्ते इसके दोनों ऑपरेंड्स में से कोई भी एक Num
(एक फ्लोट, और इस प्रकार अनुमानित) नहीं है, /
ऑपरेटर आमतौर पर 100% सटीक Rat
(एक सीमित परिशुद्धता तर्कसंगत) देता है। लेकिन यदि परिणाम का भाजक 64 बिट से अधिक हो जाता है, तो उस परिणाम को एक में बदल दिया जाता है Num
- जो सटीकता के लिए प्रदर्शन करता है, एक ट्रेडऑफ़ जिसे हम नहीं बनाना चाहते हैं। हमें इसे ध्यान में रखना होगा।
असीमित सटीकता के साथ-साथ 100% सटीकता को निर्दिष्ट करने के लिए , बस FatRat
एस का उपयोग करने के लिए ऑपरेशन को रोकना । इसे सही तरीके से करने के लिए, बस ऑपरेंड्स में से एक FatRat
( कम से कम) में से कोई एक बनाएं (और कोई नहीं Num
)
say [+] .[^500] given 1, { 1.FatRat / [×] 1 .. ++$ } ... Inf
मैंने इसे 500 दशमलव अंकों में सत्यापित किया है। मुझे उम्मीद है कि यह तब तक सटीक रहेगा जब तक कि राकु भाषा या राकोडो संकलक की कुछ सीमा से अधिक होने के कारण कार्यक्रम क्रैश नहीं हो जाता। ( कुछ चर्चा के लिए देशी पूर्णांक में 65536 बिट चौड़े बिगिंट को रद्द करने के लिए मेरा जवाब नहीं देखें ।)
फुटनोट
1 Raku कुछ महत्वपूर्ण गणितीय स्थिरांक में, सहित बनाया है e
, i
और pi
(और इसके उर्फ π
)। इस प्रकार कोई राकू में यूलर की पहचान लिख सकता है जैसे कि गणित की पुस्तकों में दिखता है। Euler की पहचान के लिए RosettaCode की Raku प्रविष्टि के लिए क्रेडिट के साथ :
# There's an invisible character between <> and iπ character pairs!
sub infix:<> (\left, \right) is tighter(&infix:<**>) { left * right };
# Raku doesn't have built in symbolic math so use approximate equal
say e**iπ + 1 ≅ 0; # True
2 डेमियन के लेख को अवश्य पढ़ा जाना चाहिए। लेकिन यह कई सराहनीय उपचारों में से एक है जो 'raku "यूलर के नंबर"' के लिए एक Google के 100+ मैचों में से एक है ।
3 अजगर के एक प्रशंसक द्वारा लिखे गए TIMTOWTDI के अधिक संतुलित विचारों में से एक के लिए TIMTOWTDI बनाम TSBO-APOO-OWTDI देखें । लेकिन वहाँ हैं बहुत दूर TIMTOWTDI लेने के लिए कमियां। इस उत्तरार्द्ध "खतरे" को प्रतिबिंबित करने के लिए, पर्ल समुदाय ने विनोदी रूप से लंबे, अपठनीय, और समझे गए TIMTOWTDIBSCINABTE को तैयार किया - इसमें एक से अधिक तरीके होते हैं लेकिन कभी-कभी संगति एक बुरी बात नहीं होती है, जिसका उच्चारण "टिम टोडी बाइकार्बोनेट" है। अजीब तरह से , लैरी ने रकु के डिजाइन के लिए बाइकार्बोनेट लगाया और डेमियन इसे e
रकु में कंप्यूटिंग के लिए लागू करता है ।