यह एक दिलचस्प चर्चा है। मुझे लगता है कि @ फ्लोडेल का उदाहरण उत्कृष्ट है। हालाँकि, मुझे लगता है कि यह मेरी बात को दर्शाता है (और @koshke इस पर टिप्पणी में उल्लेख करता है) जो returnसमझ में आता है जब आप एक कार्यात्मक कोडिंग शैली के बजाय एक अनिवार्य का उपयोग करते हैं ।
इस बिंदु पर विश्वास करने के लिए नहीं, लेकिन मैंने fooइस तरह से फिर से लिखा होगा :
foo = function() ifelse(a,a,b)
एक कार्यात्मक शैली राज्य परिवर्तनों से बचती है, जैसे कि मूल्य का भंडारण output। इस शैली में, returnजगह से बाहर है; fooगणितीय फ़ंक्शन की तरह दिखता है।
मैं @flodel से सहमत हूं: बूलियन चर के एक जटिल प्रणाली का उपयोग barकरना कम स्पष्ट होगा, और आपके पास होने पर व्यर्थ होगा return। क्या बनाता है barताकि उत्तरदायी returnबयान है कि यह एक जरूरी शैली में लिखा जाता है। दरअसल, बूलियन चर एक कार्यात्मक शैली में बचाए गए "राज्य" परिवर्तनों का प्रतिनिधित्व करते हैं।
barकार्यात्मक शैली में फिर से लिखना मुश्किल है , क्योंकि यह सिर्फ छद्म कोड है, लेकिन विचार कुछ इस तरह है:
e_func <- function() do_stuff
d_func <- function() ifelse(any(sapply(seq(d),e_func)),2,3)
b_func <- function() {
do_stuff
ifelse(c,1,sapply(seq(b),d_func))
}
bar <- function () {
do_stuff
sapply(seq(a),b_func) # Not exactly correct, but illustrates the idea.
}
whileपाश, सबसे कठिन पुनर्लेखन के लिए हो सकता है, क्योंकि यह करने के लिए राज्य में परिवर्तन द्वारा नियंत्रित किया जाता हैं a।
कॉल के कारण होने वाली गति हानि returnनगण्य है, लेकिन returnकार्यात्मक शैली में बचने और पुन: लिखने से प्राप्त दक्षता अक्सर भारी होती है। नए उपयोगकर्ताओं को यह बताने से रोकने के लिए कि returnशायद कोई मदद नहीं करेगा, लेकिन एक कार्यात्मक शैली के लिए उन्हें मार्गदर्शन देना होगा।
@Paul returnअनिवार्य शैली में आवश्यक है क्योंकि आप अक्सर लूप में विभिन्न बिंदुओं पर फ़ंक्शन से बाहर निकलना चाहते हैं। एक कार्यात्मक शैली छोरों का उपयोग नहीं करती है, और इसलिए इसकी आवश्यकता नहीं है return। विशुद्ध रूप से कार्यात्मक शैली में, अंतिम कॉल लगभग हमेशा वांछित रिटर्न मान होता है।
पायथन में, फ़ंक्शन को एक returnबयान की आवश्यकता होती है । हालांकि, यदि आप अपने कार्य को एक कार्यात्मक शैली में क्रमादेशित करते हैं, तो आपके पास returnअपने फ़ंक्शन के अंत में केवल एक बयान होगा ।
एक और StackOverflow पोस्ट से एक उदाहरण का उपयोग करते हुए, हम कहते हैं कि हम एक फ़ंक्शन चाहते थे जो TRUEकिसी दिए गए सभी मानों में एक xअजीब लंबाई थी। हम दो शैलियों का उपयोग कर सकते हैं:
# Procedural / Imperative
allOdd = function(x) {
for (i in x) if (length(i) %% 2 == 0) return (FALSE)
return (TRUE)
}
# Functional
allOdd = function(x)
all(length(x) %% 2 == 1)
एक कार्यात्मक शैली में, स्वाभाविक रूप से लौटाया जाने वाला मान फ़ंक्शन के सिरों पर आता है। दोबारा, यह एक गणितीय कार्य की तरह दिखता है।
@GSee में उल्लिखित चेतावनियाँ ?ifelseनिश्चित रूप से दिलचस्प हैं, लेकिन मुझे नहीं लगता कि वे समारोह के उपयोग को रोकने की कोशिश कर रहे हैं। वास्तव में, ifelseस्वचालित रूप से वेक्टरिंग कार्यों का लाभ है। उदाहरण के लिए, थोड़ा संशोधित संस्करण पर विचार करें foo:
foo = function(a) { # Note that it now has an argument
if(a) {
return(a)
} else {
return(b)
}
}
यह फ़ंक्शन ठीक काम करता है जब length(a)1. होता है, लेकिन यदि आप fooएक के साथ फिर से लिखते हैंifelse
foo = function (a) ifelse(a,a,b)
अब fooकिसी भी लम्बाई पर काम करता है a। वास्तव में, यह तब भी काम करेगा जब aमैट्रिक्स है। एक मूल्य को उसी आकार में वापस करना जैसा testकि एक विशेषता है जो वैश्वीकरण में मदद करता है, समस्या नहीं।
returnपिछले उदाहरण में भी अनावश्यक है। हटानेreturnसे यह थोड़ा तेज़ हो सकता है, लेकिन मेरे विचार में ऐसा इसलिए है क्योंकि R को एक मजेदार प्रोग्रामिंग भाषा कहा जाता है।