कैसे एक शुद्ध कार्यात्मक प्रोग्रामिंग भाषा असाइनमेंट स्टेटमेंट के बिना प्रबंधित करें?


26

प्रसिद्ध SICP को पढ़ते समय, मैंने पाया कि लेखक अध्याय 3 में योजना के असाइनमेंट स्टेटमेंट को प्रस्तुत करने के लिए अनिच्छुक प्रतीत होते हैं। मैं पाठ और इस तरह के समझ को पढ़ता हूं कि वे ऐसा क्यों महसूस करते हैं।

जैसा कि स्कीम पहली कार्यात्मक प्रोग्रामिंग भाषा है जिसके बारे में मुझे कभी कुछ पता है, मुझे आश्चर्य है कि कुछ कार्यात्मक प्रोग्रामिंग भाषाएं हैं (निश्चित रूप से योजना नहीं) असाइनमेंट के बिना कर सकती हैं।

पुस्तक के प्रस्तावों का उदाहरण दें, उदाहरण का उपयोग करें bank account। यदि कोई असाइनमेंट स्टेटमेंट नहीं है, तो यह कैसे किया जा सकता है? balanceचर को कैसे बदलें ? मैं ऐसा इसलिए पूछता हूं क्योंकि मुझे पता है कि कुछ तथाकथित शुद्ध कार्यात्मक भाषाएं हैं और ट्यूरिंग पूर्ण सिद्धांत के अनुसार, यह भी किया जाना चाहिए।

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

ऊपर उल्लिखित उदाहरण यहाँ है:

(define (make-withdraw balance)
    (lambda (amount)
        (if (>= balance amount)
            (begin (set! balance (- balance amount))
                balance)
            "Insufficient funds")))

तो इसमें परिवर्तन balanceद्वारा set!। मेरे लिए यह वर्ग सदस्य को बदलने के लिए एक वर्ग विधि की तरह लग रहा है balance

जैसा कि मैंने कहा, मैं कार्यात्मक प्रोग्रामिंग भाषाओं से परिचित नहीं हूं, इसलिए यदि मैंने उनके बारे में कुछ गलत कहा, तो बेझिझक इंगित करें।


1
विशुद्ध रूप से कार्यात्मक भाषा सीखने के बारे में: मैं जरूरी नहीं कि तुरंत ऐसा करने की सलाह दूं। यदि आप हास्केल सीखते हैं, तो बिना परिवर्तनशील चर के प्रोग्राम कैसे लिखना है, यह सीखने के अलावा, आपको आलस्य और हास्केल के आईओ प्रदर्शन करने के तरीके के बारे में भी सीखना होगा। यह एक बार में थोड़ा बहुत हो सकता है। यदि आप परिवर्तनशील राज्य के बिना कार्यक्रम लिखना सीखना चाहते हैं, तो सबसे आसान तरीका शायद योजना कार्यक्रमों का एक गुच्छा बिना उपयोग किए set!या अन्य कार्यों के बिना लिखना होगा जो एक के साथ समाप्त होते हैं !। एक बार जब आप इसके साथ सहज हो जाते हैं, तो शुद्ध एफपी के लिए संक्रमण आसान होना चाहिए।
sepp2k

जवाबों:


21

यदि कोई असाइनमेंट स्टेटमेंट नहीं है, तो यह कैसे किया जा सकता है? बैलेंस चर को कैसे बदलना है?

आप कुछ प्रकार के असाइनमेंट ऑपरेटर के बिना चर नहीं बदल सकते।

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

काफी नहीं। यदि कोई भाषा ट्यूरिंग पूर्ण है तो इसका अर्थ है कि यह किसी भी चीज़ की गणना कर सकता है जो किसी भी अन्य ट्यूरिंग पूर्ण भाषा की गणना कर सकती है। इसका मतलब यह नहीं है कि इसके पास हर सुविधा है जो अन्य भाषाओं में है।

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

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


चूंकि आपने एक उदाहरण के लिए कहा था, तो आइए एक जरूरी कार्यक्रम पर विचार करें जो आपके मेक-विथ फंक्शन (छद्म कोड में) का उपयोग करता है। यह कार्यक्रम उपयोगकर्ता को किसी खाते से वापस लेने, उसे जमा करने या खाते में धनराशि की क्वेरी करने की अनुमति देता है:

account = make-withdraw(0)
ask for input until the user enters "quit"
    if the user entered "withdraw $x"
        account(x)
    if the user entered "deposit $x"
        account(-x)
    if the user entered "query"
        print("The balance of the account is " + account(0))

यहां एक ही प्रोग्राम को म्यूटेबल-वेरिएबल्स का उपयोग किए बिना लिखने का एक तरीका है (मैं प्रासंगिक रूप से पारदर्शी आईओ के साथ परेशान नहीं करूंगा क्योंकि प्रश्न ऐसा नहीं था):

function IO_loop(balance):
    ask for input
    if the user entered "withdraw $x"
        IO_loop(balance - x)
    if the user entered "deposit $x"
        IO_loop(balance + x)
    if the user entered "query"
        print("The balance of the account is " + balance)
        IO_loop(balance)
    if the user entered "quit"
        do nothing

 IO_loop(0)

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


मैं आपकी बात देख सकता हूं लेकिन यह देखना चाहता हूं कि मैं एक ऐसा कार्यक्रम चाहता हूं जो बैंक खाते का अनुकरण भी करे और ये चीजें (निकासी और जमा) भी कर सकता है, तो क्या ऐसा करने का कोई आसान तरीका है?
गिन्नुहोज

@Gnijuohz यह हमेशा इस बात पर निर्भर करता है कि आप किस समस्या को हल करने की कोशिश कर रहे हैं। उदाहरण के लिए यदि आपके पास एक शुरुआती शेष राशि और निकासी और जमा की सूची है और आप उन निकासी और जमा के बाद शेष राशि जानना चाहते हैं, तो आप जमा राशि की राशि की गणना कर सकते हैं और निकासी का योग घटा सकते हैं और प्रारंभिक शेष राशि में जोड़ सकते हैं। । तो कोड में है कि होगा newBalance = startingBalance + sum(deposits) - sum(withdrawals)
sepp2k

1
@Gnijuohz मैंने अपने उत्तर में एक उदाहरण कार्यक्रम जोड़ा है।
sepp2k

समय और प्रयासों के लिए धन्यवाद जो आपने लिखित में दिया और उत्तर को फिर से लिखना! :)
गनीजोह

मैं यह जोड़ना चाहूंगा कि निरंतरता का उपयोग उस योजना को प्राप्त करने का एक माध्यम हो सकता है (जब तक आप निरंतरता के लिए एक तर्क पारित कर सकते हैं?)
Dader51

11

आप सही हैं कि यह एक वस्तु पर एक विधि की तरह लग रहा है। ऐसा इसलिए है क्योंकि यह अनिवार्य रूप से यही है। lambdaसमारोह को बंद करने कि बाहरी चर खींचती है balanceइसके दायरे में। एक ही बाहरी चर (एस) पर बंद होने और एक ही वस्तु पर कई विधियां होने के बाद, एक ही वस्तु को करने के लिए दो अलग-अलग सार होते हैं, और यदि आप दोनों प्रतिमानों को समझते हैं, तो किसी को दूसरे के संदर्भ में लागू किया जा सकता है।

शुद्ध कार्यात्मक भाषाओं को संभालने का तरीका धोखा है। उदाहरण के लिए, हास्केल में यदि आप किसी बाहरी स्रोत से इनपुट पढ़ना चाहते हैं, (जो निश्चित रूप से nondeterministic है, और जरूरी नहीं कि दो बार आप इसे दोहराएंगे तो वही परिणाम देगा), यह कहने के लिए एक सनक चाल का उपयोग करता है "हम" यह अन्य दिखावा चर मिला जो दुनिया के बाकी हिस्सों की स्थिति का प्रतिनिधित्व करता है , और हम इसकी प्रत्यक्ष रूप से जांच नहीं कर सकते, लेकिन इनपुट पढ़ना एक शुद्ध कार्य है जो बाहरी दुनिया की स्थिति लेता है और सटीक इनपुट देता है जो सटीक स्थिति देता है हमेशा बाहरी दुनिया के नए राज्य को प्रस्तुत करेगा। " (यह एक सरलीकृत स्पष्टीकरण है, निश्चित रूप से वास्तव में काम करने के तरीके पर पढ़ना आपके मस्तिष्क को गंभीरता से तोड़ देगा।)

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


मुझे वास्तव में हमारे उत्तर और हास्केल के उदाहरण में दिलचस्पी है, लेकिन इसके बारे में ज्ञान की कमी के कारण मैं आपके उत्तर के अंतिम भाग (अच्छी तरह से, दूसरा भाग :() को पूरी तरह से समझ नहीं पा रहा हूं
Gnijuohz

3
@Gnijuohz अंतिम पैराग्राफ कह रहा है कि b = makeWithdraw(42); b(1); b(2); b(3); print(b(4))आप के बजाय बस कर सकते हैं b = 42; b1 = withdraw(b1, 1); b2 = withdraw(b1, 2); b3 = withdraw(b2, 3); print(withdraw(b3, 4));जहां withdrawबस के रूप में परिभाषित किया गया है withdraw(balance, amount) = balance - amount
sepp2k

3

"एकाधिक-असाइनमेंट ऑपरेटर" एक भाषा सुविधा का एक उदाहरण है, जो आम तौर पर बोल रहा है, इसके दुष्प्रभाव हैं, और कार्यात्मक भाषाओं के कुछ उपयोगी गुणों (जैसे आलसी-मूल्यांकन) के साथ असंगत है।

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

अपने विशिष्ट उदाहरण में, आप सही हैं - सेट! ऑपरेटर है एक काम। यह नहीं एक पक्ष प्रभाव मुक्त ऑपरेटर, और यह एक जगह है जहां प्रोग्रामिंग करने के लिए एक पूरी तरह कार्यात्मक दृष्टिकोण के साथ योजना टूट जाता है।

अंततः, किसी भी विशुद्ध रूप से कार्यात्मक भाषा को कुछ समय के लिए विशुद्ध रूप से कार्यात्मक दृष्टिकोण के साथ तोड़ना होगा - उपयोगी कार्यक्रमों के विशाल बहुमत दुष्प्रभाव करते हैं। यह कहाँ करना है, इसका निर्णय आम तौर पर सुविधा की बात है, और भाषा डिजाइनर प्रोग्रामर को सर्वोच्च कार्यात्मकता प्रदान करने का निर्णय लेने का प्रयास करेंगे जहां विशुद्ध रूप से कार्यात्मक दृष्टिकोण के साथ, अपने कार्यक्रम और समस्या डोमेन के लिए उपयुक्त है।


"अंततः, किसी भी विशुद्ध रूप से कार्यात्मक भाषा को कुछ समय के लिए विशुद्ध रूप से कार्यात्मक दृष्टिकोण के साथ तोड़ना पड़ता है - अधिकांश उपयोगी कार्यक्रमों के दुष्प्रभाव होते हैं" सच है, लेकिन फिर आप आईओ और ऐसा करने के बारे में बात कर रहे हैं। बहुत से उपयोगी कार्यक्रम बिना परिवर्तनशील चर के लिखे जा सकते हैं।
sepp2k

1
... और उपयोगी कार्यक्रमों के "विशाल बहुमत" से, आपका मतलब "सब" है, है ना? मुझे किसी ऐसे कार्यक्रम के अस्तित्व की संभावना की कल्पना करने में भी कठिनाई हो रही है जिसे "उपयोगी" कहा जा सकता है जो I / O नहीं करता है, एक ऐसा कार्य जिसमें दोनों दिशाओं में साइड इफेक्ट्स की आवश्यकता होती है।
मेसन व्हीलर

@MasonWheeler SQL प्रोग्राम IO को ऐसे नहीं करते हैं। उन कार्यों का एक गुच्छा लिखना भी असामान्य नहीं है जो एक ऐसी भाषा में IO नहीं करते हैं जिसमें REPL होता है और फिर उन्हें REPL से कॉल किया जाता है। यह पूरी तरह से उपयोगी हो सकता है यदि आपके लक्षित दर्शक आरईपीएल का उपयोग करने में सक्षम हैं (विशेषकर यदि आपके लक्षित दर्शक आप हैं)।
sepp2k

1
@MasonWheeler: सिर्फ एक एकल, सरल काउंटर-उदाहरण: पीआई के एन अंकों की गणना के लिए किसी भी I / O की आवश्यकता नहीं है। यह "केवल" गणित और चर है। केवल आवश्यक इनपुट n है और रिटर्न वैल्यू Pi (से n अंक) है।
जोकिम सॉयर

1
@ जोकिम सॉर अंततः आप परिणाम को स्क्रीन पर प्रिंट करना चाहेंगे, या अन्यथा उपयोगकर्ता को इस पर रिपोर्ट करेंगे। और शुरू में आप कहीं से कार्यक्रम में कुछ स्थिरांक लोड करना चाहते हैं। इसलिए, यदि आप पांडित्यपूर्ण होना चाहते हैं, तो सभी उपयोगी कार्यक्रमों को कुछ बिंदु पर आईओ करना पड़ता है, भले ही यह तुच्छ मामले हैं जो अंतर्निहित हैं और हमेशा प्रोग्रामर द्वारा पर्यावरण से छिपे हुए हैं
ब्लूबेरी

3

विशुद्ध रूप से कार्यात्मक भाषा में, एक स्ट्रीम ट्रांसफ़र फ़ंक्शन के रूप में एक बैंक खाता ऑब्जेक्ट प्रोग्राम करेगा। ऑब्जेक्ट को खाता मालिकों (या जो कोई भी) से अनुरोधों की संभावित अनंत धारा तक अनुरोधों की एक अनंत धारा से एक फ़ंक्शन के रूप में माना जाता है। फ़ंक्शन एक प्रारंभिक संतुलन के साथ शुरू होता है, और एक नई शेष राशि की गणना करने के लिए इनपुट स्ट्रीम में प्रत्येक अनुरोध को संसाधित करता है, जिसे फिर से स्ट्रीम के शेष को संसाधित करने के लिए पुनरावर्ती कॉल पर वापस भेज दिया जाता है। (मुझे याद है कि SICP पुस्तक के दूसरे भाग में स्ट्रीम-ट्रांसफार्मर प्रतिमान की चर्चा करता है।)

इस प्रतिमान के एक अधिक विस्तृत संस्करण को "कार्यात्मक प्रतिक्रियाशील प्रोग्रामिंग" कहा जाता है, जिसकी चर्चा स्टैकऑवरफ्लो पर यहां की गई है

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

अस्वीकरण : मैं शुद्ध कार्यात्मक प्रोग्रामिंग के चर्च से संबंधित नहीं हूं। वास्तव में, मैं किसी भी चर्च से संबंधित नहीं हूं :-)


मुझे लगता है कि आप किसी मंदिर से संबंधित हैं? :
गनीजोह

1
स्वतंत्र सोच का मंदिर। वहां कोई प्रचारक नहीं।
उदय रेड्डी

2

यह संभव नहीं है एक कार्यक्रम 100% कार्यात्मक बनाने के लिए अगर यह कुछ भी उपयोगी माना जाता है। (यदि साइड इफेक्ट्स की आवश्यकता नहीं है, तो पूरे विचार को एक निरंतर संकलन समय तक कम किया जा सकता है) वापस लेने के उदाहरण की तरह आप अधिकांश प्रक्रियाओं को कार्यात्मक बना सकते हैं लेकिन अंततः आपको उन प्रक्रियाओं की आवश्यकता होगी जिनके साइड इफेक्ट्स (उपयोगकर्ता से इनपुट), कंसोल के लिए आउटपुट)। उसने कहा कि आप अपने अधिकांश कोड को क्रियाशील बना सकते हैं और उस हिस्से को परीक्षण करना आसान होगा, यहां तक ​​कि स्वचालित रूप से भी। फिर आप इनपुट / आउटपुट / डेटाबेस / ... करने के लिए कुछ आवश्यक कोड बनाते हैं, जिसमें डिबगिंग की आवश्यकता होती है, लेकिन अधिकांश कोड को साफ रखने से यह बहुत अधिक काम नहीं होगा। मैं आपके वापस लेने के उदाहरण का उपयोग करूंगा:

(define +no-founds+ "Insufficient funds")

;; functional withdraw
(define (make-withdraw balance amount)
    (if (>= balance amount)
        (- balance amount)
        +no-founds+))

;; functional atm loop
(define (atm balance thunk)
  (let* ((amount (thunk balance)) 
         (new-balance (make-withdraw balance amount)))
    (if (eqv? new-balance +no-founds+)
        (cons +no-founds+ '())
        (cons (list 'withdraw amount 'balance new-balance) (atm new-balance thunk)))))

;; functional balance-line -> string 
(define (balance->string x)
  (if (eqv? x +no-founds+)
      (string-append +no-founds+ "\n")
      (if (null? x)
          "\n"
          (let ((first-token (car x)))
            (string-append
             (cond ((symbol? first-token) (symbol->string first-token))
                   (else (number->string first-token)))
             " "
             (balance->string (cdr x)))))))

;; functional thunk to test  
(define (input-10 x) 10) ;; define a purly functional input-method

;; since all procedures involved are functional 
;; we expect the same result every time.
;; we use this to test atm and make-withdraw
(apply string-append (map balance->string (atm 100 input-10)))

;; no program can be purly functional in any language.
;; From here on there are imperative dirty procedures!

;; A procedure to get input from user is needed. 
;; Side effects makes it imperative
(define (user-input balance)
  (display "You have $")
  (display balance)
  (display " founds. How much to withdraw? ")
  (read))

;; We need a procedure to print stuff to the console 
;; as well. Side effects makes it imperative
(define (pretty-print-result x)
  (for-each (lambda (x) (display (balance->string x))) x))

;; use imperative procedure with atm.
(pretty-print-result (atm 100 user-input))

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


कार्यक्रम के कार्यात्मक भागों और गैर शुद्ध कार्यात्मक भागों के बारे में व्यापक उदाहरण और यथार्थवादी स्पष्टीकरण के लिए +1 और एफपी फिर भी क्यों मायने रखता है इसका उल्लेख करना।
ज़ेलफिर कलस्टहल

1

असाइनमेंट खराब संचालन है क्योंकि यह राज्य-स्थान को दो भागों में विभाजित करता है, पहले-असाइनमेंट और उसके बाद असाइनमेंट। इससे यह ट्रैक करने में कठिनाई होती है कि प्रोग्राम निष्पादन के दौरान चर को कैसे बदला जा रहा है। कार्यात्मक भाषाओं में निम्नलिखित चीजें असाइनमेंट की जगह ले रही हैं:

  1. मान वापस करने के लिए फ़ंक्शन पैरामीटर सीधे जुड़े हुए हैं
  2. मौजूदा वस्तुओं को संशोधित करने के बजाय विभिन्न वस्तुओं को चुनना।
  3. नए आलसी मूल्यांकन मूल्यों का निर्माण
  4. सभी संभव वस्तुओं को सूचीबद्ध करना , न कि केवल उन चीजों को जो स्मृति में होना चाहिए
  5. कोई दुष्प्रभाव नहीं

यह पता चला सवाल का पता नहीं लगता है। आप शुद्ध कार्यात्मक भाषा में बैंक खाता ऑब्जेक्ट कैसे प्रोग्राम करते हैं?
उदय रेड्डी

यह सिर्फ एक बैंक खाते के रिकॉर्ड को दूसरे में बदलने का कार्य करता है। कुंजी यह है कि जब ऐसे परिवर्तन होते हैं, तो मौजूदा वस्तुओं को संशोधित करने के बजाय नई वस्तुओं को चुना जाता है।
tp1

जब आप एक बैंक खाते के रिकॉर्ड को दूसरे में बदलते हैं, तो आप चाहते हैं कि ग्राहक अगले लेनदेन को नए रिकॉर्ड पर करे, न कि पुराने को। ग्राहक के लिए "संपर्क बिंदु" को वर्तमान रिकॉर्ड की ओर इंगित करने के लिए लगातार अपडेट किया जाना चाहिए। यह "संशोधन" का एक मौलिक विचार है। बैंक खाता "ऑब्जेक्ट" बैंक खाता रिकॉर्ड नहीं हैं।
उदय रेड्डी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.