मैंने प्रक्रियात्मक प्रोग्रामिंग और कार्यात्मक प्रोग्रामिंग दोनों के लिए विकिपीडिया लेख पढ़ा है , लेकिन मैं अभी भी थोड़ा भ्रमित हूं। क्या कोई इसे कोर तक उबाल सकता है?
मैंने प्रक्रियात्मक प्रोग्रामिंग और कार्यात्मक प्रोग्रामिंग दोनों के लिए विकिपीडिया लेख पढ़ा है , लेकिन मैं अभी भी थोड़ा भ्रमित हूं। क्या कोई इसे कोर तक उबाल सकता है?
जवाबों:
एक कार्यात्मक भाषा (आदर्श रूप से) आपको एक गणितीय फ़ंक्शन, यानी एक फ़ंक्शन लिखने की अनुमति देती है जो n तर्क लेती है और एक मान लौटाती है। यदि प्रोग्राम निष्पादित किया जाता है, तो यह फ़ंक्शन तार्किक रूप से आवश्यकतानुसार मूल्यांकन किया जाता है। 1
दूसरी ओर एक प्रक्रियात्मक भाषा, अनुक्रमिक चरणों की एक श्रृंखला करती है । (अनुक्रमिक तर्क को कार्यात्मक तर्क में बदलने का एक तरीका है जिसे निरंतरता गुजर शैली कहा जाता है ।)
परिणामस्वरूप, एक विशुद्ध रूप से कार्यात्मक कार्यक्रम हमेशा एक इनपुट के लिए समान मूल्य प्राप्त करता है, और मूल्यांकन का क्रम अच्छी तरह से परिभाषित नहीं है; जिसका अर्थ है कि उपयोगकर्ता इनपुट या यादृच्छिक मूल्यों जैसे अनिश्चित मूल्य विशुद्ध रूप से कार्यात्मक भाषाओं में मॉडल के लिए कठिन हैं।
1 इस उत्तर में सब कुछ के रूप में, यह एक सामान्यीकरण है। यह संपत्ति, एक संगणना का मूल्यांकन जब उसके परिणाम को क्रमिक रूप से जहां इसे कहा जाता है, के बजाय "आलस्य" के रूप में जाना जाता है। सभी कार्यात्मक भाषाएं वास्तव में सार्वभौमिक रूप से आलसी नहीं हैं, न ही आलसीपन कार्यात्मक प्रोग्रामिंग तक सीमित है। बल्कि, यहां दिया गया वर्णन विभिन्न प्रोग्रामिंग शैलियों के बारे में सोचने के लिए एक "मानसिक ढांचा" प्रदान करता है जो अलग और विपरीत श्रेणियां नहीं हैं, बल्कि तरल विचार हैं।
मूल रूप से दो शैलियों, यिन और यांग की तरह हैं। एक व्यवस्थित है, जबकि दूसरी अराजक। ऐसी स्थितियां हैं जब कार्यात्मक प्रोग्रामिंग स्पष्ट विकल्प है, और अन्य परिस्थितियां थीं प्रक्रियात्मक प्रोग्रामिंग बेहतर विकल्प है। यही कारण है कि कम से कम दो भाषाएं हैं जो हाल ही में एक नए संस्करण के साथ सामने आई हैं, जो दोनों प्रोग्रामिंग शैलियों को गले लगाती हैं। ( पर्ल 6 और डी 2 )
sub factorial ( UInt:D $n is copy ) returns UInt {
# modify "outside" state
state $call-count++;
# in this case it is rather pointless as
# it can't even be accessed from outside
my $result = 1;
loop ( ; $n > 0 ; $n-- ){
$result *= $n;
}
return $result;
}
int factorial( int n ){
int result = 1;
for( ; n > 0 ; n-- ){
result *= n;
}
return result;
}
( विकिपीडिया से कॉपी किया गया );
fac :: Integer -> Integer
fac 0 = 1
fac n | n > 0 = n * fac (n-1)
या एक पंक्ति में:
fac n = if n > 0 then n * fac (n-1) else 1
proto sub factorial ( UInt:D $n ) returns UInt {*}
multi sub factorial ( 0 ) { 1 }
multi sub factorial ( $n ) { $n * samewith $n-1 } # { $n * factorial $n-1 }
pure int factorial( invariant int n ){
if( n <= 1 ){
return 1;
}else{
return n * factorial( n-1 );
}
}
फैक्टरियल वास्तव में यह दिखाने के लिए एक सामान्य उदाहरण है कि पर्ल 6 में नए ऑपरेटर बनाना कितना आसान है, ठीक उसी तरह जैसे आप सबरूटीन बनाएंगे। यह सुविधा पर्ल 6 में इतनी उलझी हुई है कि रकुडो कार्यान्वयन में अधिकांश ऑपरेटरों को इस तरह से परिभाषित किया गया है। यह आपको मौजूदा ऑपरेटरों के लिए अपने स्वयं के बहु उम्मीदवारों को जोड़ने की अनुमति देता है।
sub postfix:< ! > ( UInt:D $n --> UInt )
is tighter(&infix:<*>)
{ [*] 2 .. $n }
say 5!; # 120
यह उदाहरण श्रेणी निर्माण ( 2..$n
) और सूची में कमी मेटा-ऑपरेटर ( [ OPERATOR ] LIST
संख्यात्मक इन्फिक्स गुणन ऑपरेटर के साथ संयुक्त) को भी दिखाता है । ( *
)
यह यह भी दर्शाता है कि आप --> UInt
इसके बजाय हस्ताक्षर में डाल सकते हैं returns UInt
।
(आप बिना किसी तर्क के कॉल किए 2
जाने पर मल्टीपल "ऑपरेटर" के रूप में रेंज शुरू करने के साथ वापस आ सकते हैं 1
)
sub postfix:<!> ($n) { [*] 1..$n }
No operation can have side effects
आप इसे विस्तृत कर सकते हैं?
sub foo( $a, $b ){ ($a,$b).pick }
← हमेशा एक ही इनपुट के लिए एक ही आउटपुट वापस नहीं करता है, जबकि निम्नलिखित करता हैsub foo( $a, $b ){ $a + $b }
मैंने इस परिभाषा को कहीं और नहीं देखा है, लेकिन मुझे लगता है कि यह अंतर यहाँ दिए गए मतभेदों को काफी अच्छी तरह बताता है:
कार्यात्मक प्रोग्रामिंग भावों पर केंद्रित है
प्रक्रियात्मक प्रोग्रामिंग बयानों पर केंद्रित है
भावों का मान होता है। एक कार्यात्मक कार्यक्रम एक अभिव्यक्ति है जिसका मूल्य कंप्यूटर के लिए निर्देशों का एक क्रम है।
विवरण में मान नहीं होते हैं और इसके बजाय कुछ वैचारिक मशीन की स्थिति को संशोधित करते हैं।
विशुद्ध रूप से कार्यात्मक भाषा में, कोई भी कथन नहीं होगा, इस अर्थ में कि राज्य में हेरफेर करने का कोई तरीका नहीं है (उनके पास अभी भी "बयान" नाम का एक वाक्यविन्यास निर्माण हो सकता है, लेकिन जब तक यह राज्य में हेरफेर नहीं करता है, मैं इसे इस अर्थ में बयान नहीं कहूंगा। )। विशुद्ध रूप से प्रक्रियात्मक भाषा में कोई अभिव्यक्ति नहीं होगी, सब कुछ एक निर्देश होगा जो मशीन की स्थिति में हेरफेर करता है।
हास्केल विशुद्ध रूप से कार्यात्मक भाषा का एक उदाहरण होगा क्योंकि राज्य में हेरफेर करने का कोई तरीका नहीं है। मशीन कोड विशुद्ध रूप से प्रक्रियात्मक भाषा का एक उदाहरण होगा क्योंकि एक कार्यक्रम में सब कुछ एक बयान है जो मशीन के रजिस्टरों और मेमोरी की स्थिति में हेरफेर करता है।
भ्रामक हिस्सा यह है कि अधिकांश प्रोग्रामिंग भाषाओं में दोनों शामिल हैं अभिव्यक्ति और कथन , जिससे आप प्रतिमानों को मिला सकते हैं। भाषाओं को अधिक कार्यात्मक या अधिक प्रक्रियात्मक के रूप में वर्गीकृत किया जा सकता है, जिसके आधार पर वे कथन बनाम अभिव्यक्तियों के उपयोग को प्रोत्साहित करते हैं।
उदाहरण के लिए, C COBOL की तुलना में अधिक कार्यात्मक होगा क्योंकि एक फ़ंक्शन कॉल एक अभिव्यक्ति है, जबकि COBOL में एक उप कार्यक्रम को कॉल करना एक बयान है (जो साझा चर की स्थिति में हेरफेर करता है और एक मान वापस नहीं करता है)। पायथन सी की तुलना में अधिक कार्यात्मक होगा क्योंकि यह आपको शॉर्ट सर्किट मूल्यांकन (टेस्ट और पथ 1) पथ 2 का उपयोग करते हुए अभिव्यक्ति के रूप में सशर्त तर्क व्यक्त करने की अनुमति देता है यदि कथन के विपरीत)। योजना पायथन से अधिक कार्यात्मक होगी क्योंकि योजना में सब कुछ एक अभिव्यक्ति है।
आप अभी भी एक कार्यात्मक शैली में एक भाषा में लिख सकते हैं जो प्रक्रियात्मक प्रतिमान को प्रोत्साहित करती है और इसके विपरीत। यह सिर्फ कठिन और / या अधिक अजीब है जो एक प्रतिमान में लिखने के लिए है जो भाषा द्वारा प्रोत्साहित नहीं किया जाता है।
कंप्यूटर विज्ञान में, कार्यात्मक प्रोग्रामिंग एक प्रोग्रामिंग प्रतिमान है जो गणना को गणितीय कार्यों के मूल्यांकन के रूप में मानता है और राज्य और पारस्परिक डेटा से बचा जाता है। यह कार्यों के अनुप्रयोग पर जोर देता है, प्रक्रियात्मक प्रोग्रामिंग शैली के विपरीत जो राज्य में परिवर्तन पर जोर देता है।
GetUserContext()
फ़ंक्शन में कभी नहीं डालूंगा , उपयोगकर्ता संदर्भ को पारित किया जाएगा। क्या यह कार्यात्मक प्रोग्रामिंग है? अग्रिम में धन्यवाद।
मेरा मानना है कि प्रक्रियात्मक / कार्यात्मक / उद्देश्य प्रोग्रामिंग एक समस्या का सामना करने के तरीके के बारे में है।
पहली शैली चरणों में सब कुछ योजना बनाती है, और एक समय में एक चरण (एक प्रक्रिया) को लागू करके समस्या को हल करती है। दूसरी ओर, कार्यात्मक प्रोग्रामिंग डिवाइड-एंड-कॉनकेयर दृष्टिकोण पर जोर देगा, जहां समस्या को उप-समस्या में विभाजित किया जाता है, फिर प्रत्येक उप-समस्या को हल किया जाता है (उस उप समस्या को हल करने के लिए एक फ़ंक्शन) और परिणाम संयुक्त होते हैं पूरी समस्या के लिए उत्तर बनाएँ। अंत में, ऑब्जेक्टिव प्रोग्रामिंग कई वस्तुओं के साथ कंप्यूटर के अंदर एक मिनी-वर्ल्ड बनाकर वास्तविक दुनिया की नकल करेगा, जिनमें से प्रत्येक में एक (कुछ) अद्वितीय विशेषताएं हैं, और दूसरों के साथ बातचीत करता है। उन इंटरैक्शन से परिणाम सामने आएगा।
प्रोग्रामिंग की प्रत्येक शैली के अपने फायदे और कमजोरियां हैं। इसलिए, कुछ ऐसा करना जैसे "शुद्ध प्रोग्रामिंग" (अर्थात विशुद्ध रूप से प्रक्रियात्मक - कोई भी ऐसा नहीं करता है, वैसे, जो अजीब तरह का है - या विशुद्ध रूप से कार्यात्मक या विशुद्ध रूप से उद्देश्यपूर्ण) बहुत मुश्किल है, अगर कुछ प्राथमिक समस्याओं को छोड़कर, असंभव नहीं है, तो विशेष रूप से एक प्रोग्रामिंग शैली के लाभ को प्रदर्शित करने के लिए डिज़ाइन किया गया है (इसलिए, हम उन लोगों को कहते हैं जो शुद्धता "वेनी": डी) को पसंद करते हैं।
फिर, उन शैलियों से, हमारे पास प्रोग्रामिंग भाषाएं हैं जिन्हें कुछ प्रत्येक शैली के लिए अनुकूलित करने के लिए डिज़ाइन किया गया है। उदाहरण के लिए, विधानसभा सभी प्रक्रियात्मक है। ठीक है, अधिकांश शुरुआती भाषाएं प्रक्रियात्मक हैं, न केवल एसम, जैसे सी, पास्कल, और (फोरट्रान, मैंने सुना)। तब, हमारे पास सभी प्रसिद्ध जावा ऑब्जेक्टिव स्कूल में हैं (वास्तव में, जावा और सी # भी "मनी-ओरिएंटेड" नामक एक वर्ग में है, लेकिन यह एक और चर्चा के अधीन है)। इसके अलावा उद्देश्य स्मालटाक है। कार्यात्मक स्कूल में, हमारे पास "लगभग कार्यात्मक" होगा (कुछ उन्हें अपवित्र माना जाता है) लिस्प परिवार और एमएल परिवार और कई "विशुद्ध रूप से कार्यात्मक" हास्केल, एर्लैंग, आदि। कई सामान्य भाषाएं जैसे पर्ल, पायथन हैं। , माणिक।
num = 1
def function_to_add_one(num):
num += 1
return num
function_to_add_one(num)
function_to_add_one(num)
function_to_add_one(num)
function_to_add_one(num)
function_to_add_one(num)
#Final Output: 2
num = 1
def procedure_to_add_one():
global num
num += 1
return num
procedure_to_add_one()
procedure_to_add_one()
procedure_to_add_one()
procedure_to_add_one()
procedure_to_add_one()
#Final Output: 6
function_to_add_one
एक समारोह है
procedure_to_add_one
एक प्रक्रिया है
यहां तक कि अगर आप पांच बार फ़ंक्शन चलाते हैं , तो हर बार यह वापस आ जाएगा 2
यदि आप प्रक्रिया को पांच बार चलाते हैं, तो पांचवें रन के अंत में यह आपको 6 देगा ।
कोनराड की टिप्पणी पर विस्तार करने के लिए:
नतीजतन, एक विशुद्ध रूप से कार्यात्मक कार्यक्रम हमेशा एक इनपुट के लिए समान मूल्य प्राप्त करता है, और मूल्यांकन का क्रम अच्छी तरह से परिभाषित नहीं है;
इस वजह से, कार्यात्मक कोड आमतौर पर समानांतर में आसान होता है। चूंकि कार्यों के कोई साइड इफेक्ट्स (आम तौर पर) नहीं होते हैं, और वे (आम तौर पर) सिर्फ अपने तर्कों पर काम करते हैं, बहुत से समसामयिक मुद्दे दूर हो जाते हैं।
कार्यात्मक प्रोग्रामिंग का उपयोग तब भी किया जाता है जब आपको साबित करने में सक्षम होने की आवश्यकता होती है अपने कोड को सही होती है। यह प्रक्रियात्मक प्रोग्रामिंग के साथ करना बहुत कठिन है (कार्यात्मक के साथ आसान नहीं है, लेकिन अभी भी आसान है)।
अस्वीकरण: मैंने वर्षों में कार्यात्मक प्रोग्रामिंग का उपयोग नहीं किया है, और केवल हाल ही में इसे फिर से देखना शुरू कर दिया है, इसलिए मैं यहां पूरी तरह से सही नहीं हो सकता। :)
एक बात जो मैंने वास्तव में यहाँ नहीं देखी थी, वह यह है कि हास्केल जैसी आधुनिक कार्यात्मक भाषाएं स्पष्ट पुनरावर्तन की तुलना में प्रवाह नियंत्रण के लिए प्रथम श्रेणी के कार्यों पर वास्तव में अधिक हैं। आपको हास्केल में फैक्टरलेरी को फिर से परिभाषित करने की आवश्यकता नहीं है, जैसा कि ऊपर किया गया था। मुझे ऐसा कुछ लगता है
fac n = foldr (*) 1 [1..n]
एक पूरी तरह से मुहावरेदार निर्माण है, और स्पष्ट पुनरावृत्ति की तुलना में लूप का उपयोग करने के लिए आत्मा में बहुत करीब है।
प्रक्रियात्मक भाषाएं राज्य का ट्रैक रखना (चर का उपयोग करना) और चरणों के अनुक्रम के रूप में निष्पादित करने के लिए जाती हैं। विशुद्ध रूप से कार्यात्मक भाषाएं राज्य का ट्रैक नहीं रखती हैं, अपरिवर्तनीय मूल्यों का उपयोग करती हैं, और निर्भरता की एक श्रृंखला के रूप में निष्पादित करती हैं। कई मामलों में कॉल स्टैक की स्थिति उस जानकारी को धारण करेगी, जो उस प्रक्रिया के बराबर होगी जो प्रक्रियात्मक कोड में राज्य चर में संग्रहीत की जाएगी।
रिकर्सियन कार्यात्मक शैली प्रोग्रामिंग का एक उत्कृष्ट उदाहरण है।
कोनराड ने कहा:
परिणामस्वरूप, एक विशुद्ध रूप से कार्यात्मक कार्यक्रम हमेशा एक इनपुट के लिए समान मूल्य प्राप्त करता है, और मूल्यांकन का क्रम अच्छी तरह से परिभाषित नहीं है; जिसका अर्थ है कि उपयोगकर्ता इनपुट या यादृच्छिक मूल्यों जैसे अनिश्चित मूल्य विशुद्ध रूप से कार्यात्मक भाषाओं में मॉडल के लिए कठिन हैं।
विशुद्ध रूप से कार्यात्मक कार्यक्रम में मूल्यांकन का क्रम (विशेष रूप से आलस्य के साथ) या यहां तक कि महत्वहीन होने के कारण कठिन (एर) हो सकता है, लेकिन मुझे लगता है कि यह कहना कि यह अच्छी तरह से परिभाषित नहीं है, ऐसा लगता है जैसे आप बता नहीं सकते कि आपका कार्यक्रम चल रहा है सब पर काम करने के लिए!
शायद एक बेहतर व्याख्या यह होगी कि कार्यात्मक कार्यक्रमों में नियंत्रण प्रवाह तब होता है जब किसी फ़ंक्शन के तर्कों के मूल्य की आवश्यकता होती है। इस बारे में अच्छी बात यह है कि अच्छी तरह से लिखा कार्यक्रमों में, राज्य स्पष्ट हो जाता है: प्रत्येक कार्य के बजाय मापदंडों मनमाने ढंग से के रूप में अपनी आदानों को सूचीबद्ध munging वैश्विक राज्य। तो कुछ स्तर पर, एक समय में एक फ़ंक्शन के संबंध में मूल्यांकन के आदेश के बारे में तर्क करना आसान है । प्रत्येक फ़ंक्शन बाकी ब्रह्मांड को अनदेखा कर सकता है और इस पर ध्यान केंद्रित कर सकता है कि उसे क्या करने की आवश्यकता है। संयुक्त होने पर, फ़ंक्शन को समान [1] काम करने की गारंटी दी जाती है क्योंकि वे अलगाव में होंगे।
... उपयोगकर्ता इनपुट या यादृच्छिक मूल्यों जैसे अनिश्चित मूल्य विशुद्ध रूप से कार्यात्मक भाषाओं में मॉडल के लिए कठिन हैं।
विशुद्ध रूप से कार्यात्मक कार्यक्रमों में इनपुट समस्या का समाधान एक पर्याप्त रूप से शक्तिशाली अमूर्तता का उपयोग करके एक अनिवार्य भाषा को एक डीएसएल के रूप में एम्बेड करना है । अनिवार्य (या गैर-शुद्ध कार्यात्मक) भाषाओं में यह आवश्यक नहीं है क्योंकि आप "धोखा" दे सकते हैं और राज्य को अस्पष्ट रूप से पारित कर सकते हैं और मूल्यांकन का क्रम स्पष्ट है (आप इसे पसंद करते हैं या नहीं)। इस "धोखा" और हर कार्य के लिए सभी मापदंडों का मजबूर मूल्यांकन के कारण, अनिवार्य भाषाओं में 1) आप अपना स्वयं का नियंत्रण प्रवाह तंत्र बनाने की क्षमता खो देते हैं (मैक्रोज़ के बिना), 2) कोड स्वाभाविक रूप से थ्रेड सुरक्षित और / या समानांतर नहीं है। डिफ़ॉल्ट रूप से, 3) और पूर्ववत (समय यात्रा) जैसी किसी चीज़ को लागू करने से सावधानीपूर्वक काम होता है (अनिवार्य प्रोग्रामर को पुराने मूल्य प्राप्त करने के लिए एक नुस्खा स्टोर करना चाहिए!), जबकि शुद्ध कार्यात्मक प्रोग्रामिंग आपको ये सभी चीजें खरीदता है - और कुछ और। भूल गए हैं - "मुफ्त में"।
मुझे उम्मीद है कि यह उत्साह की तरह नहीं है, मैं सिर्फ कुछ परिप्रेक्ष्य जोड़ना चाहता था। इम्पीरेटिव प्रोग्रामिंग और विशेष रूप से सी # 3.0 जैसी शक्तिशाली भाषाओं में मिश्रित प्रतिमान प्रोग्रामिंग अभी भी पूरी तरह से प्रभावी तरीके से काम कर रहे हैं और कोई चांदी की गोली नहीं है ।
[१] ... संभवतः सम्मान स्मृति उपयोग के साथ (सी। एच। एफ। और हस्केल में फोल्ड ’)।
कोनराड की टिप्पणी पर विस्तार करने के लिए:
और मूल्यांकन का क्रम अच्छी तरह से परिभाषित नहीं है
कुछ कार्यात्मक भाषाओं में आलसी मूल्यांकन कहा जाता है। जिसका अर्थ है कि किसी फ़ंक्शन को तब तक निष्पादित नहीं किया जाता है जब तक कि मूल्य की आवश्यकता नहीं होती है। उस समय तक फ़ंक्शन ही है जो चारों ओर से गुजरता है।
प्रक्रियात्मक भाषाएँ चरण 1 चरण 2 चरण 3 हैं ... यदि चरण 2 में आप 2 + 2 जोड़ते हैं, तो यह सही है। आलसी मूल्यांकन में आप कहेंगे कि 2 + 2 जोड़ेंगे, लेकिन यदि परिणाम का उपयोग कभी नहीं किया जाता है, तो यह कभी भी जोड़ नहीं देता है।
यदि आपके पास एक मौका है, तो मैं लिस्प / योजना की एक प्रति प्राप्त करने और उसमें कुछ परियोजनाएं करने की सिफारिश करूंगा। हाल ही में बैंडवागन्स बनने वाले अधिकांश विचारों को लिस्प दशकों पहले व्यक्त किया गया था: कार्यात्मक प्रोग्रामिंग, निरंतरता (क्लोजर के रूप में), कचरा संग्रह, यहां तक कि एक्सएमएल भी।
ताकि इन सभी मौजूदा विचारों पर एक अच्छी शुरुआत हो सके और प्रतीकात्मक गणना की तरह कुछ और भी हो सके।
आपको पता होना चाहिए कि कार्यात्मक प्रोग्रामिंग किसके लिए अच्छा है और यह किसके लिए अच्छा नहीं है। यह सब कुछ के लिए अच्छा नहीं है। कुछ समस्याओं को साइड-इफेक्ट्स के संदर्भ में सबसे अच्छी तरह से व्यक्त किया जाता है, जहां एक ही सवाल अलग-अलग उत्तर देता है, जब यह पूछा जाता है।
@Creighton:
हास्केल में उत्पाद नामक एक पुस्तकालय समारोह है :
prouduct list = foldr 1 (*) list
या केवल:
product = foldr 1 (*)
इसलिए "मुहावरेदार" तथ्य
fac n = foldr 1 (*) [1..n]
बस होगा
fac n = product [1..n]
प्रक्रियात्मक प्रोग्रामिंग बयानों और सशर्त निर्माणों के अनुक्रमों को अलग-अलग ब्लॉकों में विभाजित करता है जिन्हें प्रक्रियाएं कहा जाता है जो तर्क (गैर-कार्यात्मक) मानों पर मानकीकृत हैं।
फ़ंक्शनल प्रोग्रामिंग समान है सिवाय इसके कि फ़ंक्शंस प्रथम श्रेणी के मान हैं, इसलिए उन्हें अन्य फ़ंक्शंस के तर्क के रूप में पारित किया जा सकता है और फ़ंक्शन कॉल के परिणाम के रूप में लौटाया जा सकता है।
ध्यान दें कि कार्यात्मक प्रोग्रामिंग इस व्याख्या में प्रक्रियात्मक प्रोग्रामिंग का एक सामान्यीकरण है। हालांकि, एक अल्पसंख्यक "कार्यात्मक प्रोग्रामिंग" की व्याख्या साइड-इफ़ेक्ट-मुक्त करने के लिए करता है जो हास्केल को छोड़कर सभी प्रमुख कार्यात्मक भाषाओं के लिए काफी भिन्न लेकिन अप्रासंगिक है।
अंतर को समझने के लिए, किसी को यह समझने की आवश्यकता है कि प्रक्रियात्मक और कार्यात्मक प्रोग्रामिंग दोनों के "गॉडफादर" प्रतिमान अनिवार्य प्रोग्रामिंग है ।
मूल रूप से प्रक्रियात्मक प्रोग्रामिंग केवल अनिवार्य कार्यक्रमों को संरचित करने का एक तरीका है जिसमें अमूर्तता की प्राथमिक विधि "प्रक्रिया" है। (या कुछ प्रोग्रामिंग भाषाओं में "फ़ंक्शन")। यहां तक कि ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग एक अनिवार्य कार्यक्रम को संरचित करने का एक और तरीका है, जहां राज्य वस्तुओं में घिरा हुआ है, एक "वर्तमान स्थिति" के साथ एक वस्तु बन जाता है, साथ ही इस ऑब्जेक्ट में फ़ंक्शन, विधियों और अन्य सामान का एक सेट होता है जो आपको सामान करते हैं प्रोग्रामर राज्य में हेरफेर या अपडेट करता है।
अब, कार्यात्मक प्रोग्रामिंग के संबंध में, जिस्ट अपने दृष्टिकोण में है कि यह पहचान करता है क्या मान लेने के लिए और कैसे इन मूल्यों को स्थानांतरित किया जाना चाहिए है। (इसलिए इसमें कोई राज्य नहीं है, और कोई भी परिवर्तनशील डेटा नहीं है क्योंकि यह प्रथम श्रेणी के मानों के रूप में कार्य करता है और उन्हें अन्य कार्यों के मापदंडों के रूप में पारित करता है)।
पुनश्च: प्रत्येक प्रोग्रामिंग प्रतिमान को समझने के लिए उपयोग किया जाता है, उन सभी के बीच अंतर को स्पष्ट करना चाहिए।
PSS: दिन के अंत में, प्रोग्रामिंग प्रतिमान समस्याओं को हल करने के लिए अलग-अलग दृष्टिकोण हैं।
PSS: इस कोरा उत्तर की एक महान व्याख्या है।
यहाँ कोई भी उत्तर मुहावरेदार कार्यात्मक प्रोग्रामिंग नहीं दिखाता है। पुनरावर्ती भाज्य उत्तर एफपी में पुनरावृत्ति का प्रतिनिधित्व करने के लिए बहुत अच्छा है, लेकिन अधिकांश कोड पुनरावर्ती नहीं है, इसलिए मुझे नहीं लगता कि उत्तर पूरी तरह से प्रतिनिधि है।
मान लें कि आपके पास स्ट्रिंग्स का एक arrays है, और प्रत्येक स्ट्रिंग "5" या "-200" जैसे पूर्णांक का प्रतिनिधित्व करता है। आप अपने आंतरिक परीक्षण मामले (पूर्णांक तुलना का उपयोग करके) के खिलाफ तार के इस इनपुट सरणी की जांच करना चाहते हैं। दोनों समाधान नीचे दिखाए गए हैं
arr_equal(a : [Int], b : [Str]) -> Bool {
if(a.len != b.len) {
return false;
}
bool ret = true;
for( int i = 0; i < a.len /* Optimized with && ret*/; i++ ) {
int a_int = a[i];
int b_int = parseInt(b[i]);
ret &= a_int == b_int;
}
return ret;
}
eq = i, j => i == j # This is usually a built-in
toInt = i => parseInt(i) # Of course, parseInt === toInt here, but this is for visualization
arr_equal(a : [Int], b : [Str]) -> Bool =
zip(a, b.map(toInt)) # Combines into [Int, Int]
.map(eq)
.reduce(true, (i, j) => i && j) # Start with true, and continuously && it with each value
जबकि शुद्ध कार्यात्मक भाषा आम तौर पर अनुसंधान भाषाएं होती हैं (जैसा कि वास्तविक दुनिया मुफ्त साइड-इफेक्ट्स को पसंद करती है), वास्तविक-दुनिया प्रक्रियात्मक भाषाएं उपयुक्त होने पर बहुत सरल कार्यात्मक वाक्यविन्यास का उपयोग करेंगी।
यह आमतौर पर लॉडश जैसी बाहरी लाइब्रेरी के साथ लागू किया जाता है , या उपलब्ध नई भाषाओं जैसे रस्ट के साथ बनाया जाता है । कार्यात्मक प्रोग्रामिंग का भार उठाने की तरह काम करता है / अवधारणाओं के साथ किया जाता है map
, filter
, reduce
, currying
,partial
, जिनमें से पिछले तीन आप को आगे समझने के लिए देख सकते हैं।
जंगली में उपयोग किए जाने के लिए, कंपाइलर को सामान्य रूप से कार्य करना होगा कि कार्यात्मक संस्करण को प्रक्रियात्मक संस्करण में आंतरिक रूप से कैसे परिवर्तित किया जाए, क्योंकि फ़ंक्शन कॉल ओवरहेड बहुत अधिक है। पुनरावर्ती मामलों जैसे कि फैक्टरियल दिखाया गया है ओ (एन) मेमोरी उपयोग को हटाने के लिए टेल कॉल जैसे ट्रिक का उपयोग किया जाएगा । यह तथ्य कि कोई साइड इफेक्ट नहीं है, कार्यात्मक कंपाइलरों को अंतिम बार && ret
होने पर भी अनुकूलन को लागू करने की अनुमति देता है .reduce
। जेएस में लॉडश का उपयोग करना, स्पष्ट रूप से किसी भी अनुकूलन की अनुमति नहीं देता है, इसलिए यह प्रदर्शन के लिए एक हिट है (जो आमतौर पर वेब विकास के साथ एक चिंता का विषय नहीं है)। Rust जैसी भाषाएं आंतरिक रूप से ऑप्टिमाइज़ करेंगी (और इसमें फंक्शन हैं जैसे ऑप्टिमाइज़ेशन try_fold
को असिस्ट करने के लिए && ret
)।