क्या कार्यात्मक प्रोग्रामिंग बस अलग है, या यह वास्तव में बहुत कठिन है?


12

क्या कार्यात्मक प्रोग्रामिंग बस अलग है , या यह वास्तव में बहुत कठिन है ?

किसी ऐसे व्यक्ति को कहें जिसने पहले कभी प्रोग्रामिंग नहीं सीखी है, और उसे कार्यात्मक प्रोग्रामिंग सिखाई जाती है। किसी ऐसे व्यक्ति के विरुद्ध, जिसने पहले कभी भी प्रोग्रामिंग नहीं सीखी है, और अनिवार्य प्रोग्रामिंग सिखाई जाती है। जो वह मुश्किल हो जाएगा? या वही?

मेरा सवाल है: अब समस्या कहो कि ऊंट-मामला एक इनपुट है,

ऐसा qwe_asd_zxc_rty_fgh_vbnबन जाता हैqweAsdZxcRtyFghVbn

प्रक्रियात्मक तरीका है:

  1. इसके साथ विभाजित करें _
  2. पहले आइटम को छोड़ने वाले सरणी के माध्यम से लूप
  3. प्रत्येक प्रविष्टि के लिए हम पहले अक्षर को बड़ा करते हैं
  4. एक साथ परिणाम में शामिल हों

कार्यात्मक तरीका है:

  1. अगर _वापसी नहीं मिलीinput
  2. inputपहले के साथ काटें _(जैसे कि हमें मिलता है qweऔर asd_zxc_rty_gfh_cvb)
  3. के पहले अक्षर को headसमाप्‍त करें और उसके साथ सम्‍मिलित करेंf(tail)

ठीक है अगर आपके पास एक कार्यात्मक-पृष्ठभूमि है और प्रक्रियात्मक-प्रोग्रामिंग में पर्याप्त अनुभव है, तो मैं पूछना चाहता हूं: क्या आपको प्रक्रियात्मक तरीके का पता लगाने में अधिक समय लगेगा या आपको कार्यात्मक तरीके का पता लगाने में अधिक समय लगेगा?

यदि आपके पास एक प्रक्रिया-पृष्ठभूमि है, लेकिन कार्यात्मक-प्रोग्रामिंग के साथ कई वर्षों का अनुभव है, तो मैं एक ही सवाल पूछना चाहता हूं: क्या आपको प्रक्रियात्मक तरीके का पता लगाने में अधिक समय लगेगा या कार्यात्मक का पता लगाने में आपको अधिक समय लगेगा। मार्ग?


5
एहम, "प्रक्रियात्मक तरीका" मेरे लिए पूरी तरह कार्यात्मक लगता है अगर हम mapएक उत्परिवर्ती लूप के बजाय चरण 3 के लिए उपयोग करते हैं। दूसरा तरीका यह है कि मैं केवल इस बात पर विचार करूंगा कि मानक पुस्तकालय में कोई स्प्लिट फ़ंक्शन नहीं है (जिस स्थिति में इसका उपयोग अनिवार्य समाधान की तुलना में किया जाना चाहिए जो उपयोग नहीं करता है split)।
sepp2k

8
आपके उदाहरणों के बारे में विशेष रूप से कार्यात्मक या प्रक्रियात्मक कुछ भी नहीं है। यह मुझे लगता है कि आप कार्यात्मक प्रोग्रामिंग की एक दोषपूर्ण समझ से बाहर निकालने की कोशिश कर रहे हैं। कोई आश्चर्य नहीं कि आप असामान्य परिणाम प्राप्त कर रहे हैं।
रीन हेनरिच्स

मुझे नहीं लगता कि कार्यात्मक प्रोग्रामिंग कठिन है, यह सिर्फ अलग है। यदि आपके पास कोई प्रोग्रामिंग अनुभव नहीं है तो या तो सीखना आसान है, लेकिन किसी कारण से जब आप अनिवार्य प्रोग्रामिंग सीख लेते हैं, तो कार्यात्मक प्रोग्रामिंग मुश्किल हो जाती है।
dan_waterworth

1
मुझे लगता है कि कार्यात्मक और प्रक्रियात्मक के बीच अंतर मूट हो जाता है, क्योंकि जावास्क्रिप्ट, सी #, ग्रूवी जैसी मुख्य भाषाओं में अधिक से अधिक कार्यात्मक विशेषताएं हैं।
user281377

2
इंपीरियल प्रोग्रामिंग उन लोगों के लिए बहुत अधिक कठिन और प्रति-सहज है, जिन्हें पहले का कोई प्रोग्रामिंग अनुभव नहीं था। एक अभिव्यक्ति की तरह x=x+1एक unexpecting मस्तिष्क को उड़ा सकता है। कार्यात्मक प्रोग्रामिंग स्वाभाविक है, यह शुद्ध और दृढ़ सख्ती से गणितीय कार्यों से अधिक कुछ नहीं है।
तर्क

जवाबों:


12

बिल्कुल अलग। कार्यात्मक प्रोग्रामिंग गणित से बहुत अधिक निकटता से संबंधित है, जिससे अधिकांश लोग परिचित हैं। संपूर्ण "अपरिवर्तनीय चर" चीज केवल अनिवार्य प्रोग्रामर के लिए एक झटका है जहां "उत्परिवर्तित" मानसिकता गहन रूप से बाधित है।

नए लोगों के लिए, यह अक्सर काफी सहज होता है कि आप किसी चीज़ का मूल्य नहीं बदल सकते ।

जहां मैंने सीएस का अध्ययन किया, हमें हमारे पहले पाठ्यक्रम के रूप में एक कार्यात्मक भाषा सिखाई गई। और जो कोई भी C ++ या जावा सीखता था, वह पहले इससे जूझता था। जो लोग प्रोग्रामिंग में नए थे उन्होंने इसे आसानी से उठाया।


jalf आप प्रोग्रामिंग में नए लोगों में से एक हैं और इसे काफी आसानी से उठाया है?
पचेरियर

मैं कहीं बीच में था। मैं सी ++ और फिर से पहले कुछ पीएचपी के साथ थोड़ा-सा घूमता था, लेकिन वास्तव में अनिवार्य मानसिकता के अभ्यस्त होने के लिए पर्याप्त नहीं था। जब आप कक्षा को समग्र रूप से देखते थे तो पैटर्न बहुत स्पष्ट था। इसके अलावा, यह लगभग एक दशक पहले था, इसलिए नहीं, मैं आज प्रोग्रामिंग के लिए बिल्कुल नया नहीं हूं;)
jalf

अपरिवर्तनीय चर? क्या गणितीय प्रोग्रामिंग भाषा नहीं है? गणित में चर निश्चित रूप से परिवर्तनशील हैं, नहीं?
user56834

20

यह अलग है

जब आप प्रोग्राम करते हैं तो आप अनिवार्य रूप से जिस तरह से आप कोड में अनुवाद करते हैं, आपके विचारों और अंतिम समाधान के बीच की दूरी को "संज्ञानात्मक अंतराल" कहा जा सकता है। आप इसे पाटने के लिए जितना बड़ा अंतर उतना ही कठिन होगा।

यदि आप एक प्रक्रियात्मक पृष्ठभूमि से आते हैं, तो आपने खुद को प्रक्रियात्मक रूप से सोचने के लिए प्रशिक्षित किया होगा, इसलिए अंतराल कम होगा और फिर कार्यात्मक कोड के लिए, और इसके विपरीत।

एक प्रोग्रामिंग प्रतिमान के लिए आंतरिक रूप से किसी भी चीज़ की तुलना में आसान होने का एकमात्र तरीका यह होगा कि यदि आप पहले से ही सामान्य भाषा की तरह कुछ जानते हैं, तो आप कम अंतराल के साथ शुरू करेंगे।

कार्यात्मक और प्रक्रियात्मक एक बहुत ही तरल अवधारणा है वैसे भी और वे ओवरलैप करते हैं


4

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

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

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

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

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

नतीजा यह है कि हम अपेक्षाकृत आसानी से ऊपर की समस्या को सामान्य कर सकते हैं। परिवर्तन में सीधे '_' और "ऊपरी-मामले" को हार्ड-कोडिंग के बजाय, हालांकि, हमारे पास कुछ इस तरह हो सकता है:

s&r(pattern, transform, string) {
    if (!pattern(string))
        return string
    else
        return transform(matched part of string) + s&r(rest of string);
}

लेकिन, कुछ के विपरीत जहां हम पैटर्न को आरई के रूप में निर्दिष्ट करते हैं, हम पैटर्न को सीधे वास्तविक फ़ंक्शन के रूप में निर्दिष्ट कर सकते हैं, और अभी भी इसका उपयोग कर सकते हैं, कुछ इस प्रकार हैं:

my_pattern(string) return beginning(string) == '_';

और फिर हम उस फ़ंक्शन को s & r में पास करते हैं। अभी, यह एक बहुत ही तुच्छ कार्य है, और हमने इसे पूरी तरह से वैधानिक रूप से एन्कोड किया है। एक कार्यात्मक भाषा काफी हद तक दिलचस्प हो जाती है जब हम इसका उपयोग करते हैं जैसे हम REs कर सकते हैं, और उपयोगकर्ता इनपुट जैसी किसी चीज़ के आधार पर मक्खी पर एक पूरी तरह से नया फ़ंक्शन उत्पन्न कर सकते हैं, लेकिन एक RE के विपरीत है कि फ़ंक्शन को चलाने के लिए एक विशेष RE दुभाषिया की आवश्यकता नहीं है - यह किसी भी अन्य की तरह सिर्फ एक सामान्य कार्य।


4

यहाँ रैकेट में पूरा कोड है :

;; camelize : string -> string
(define (camelize str)
  (let ([parts (regexp-split #rx"_" str)])
    ;; result of regexp-split is never empty
    (apply string-append
           (first parts)
           (map string-titlecase (rest parts)))))

(camelize "qwe_asd_zxc_rty_fgh_vbn")
;; => "qweAsdZxcRtyFghVbn"

प्रक्रियात्मक अनुभव के साथ एक कार्यात्मक प्रोग्रामर के रूप में, मुझे नहीं लगता कि यह मुझे एक प्रक्रियात्मक समाधान का "पता लगाने" में अधिक समय लगेगा, लेकिन यह निश्चित रूप से मुझे इसे टाइप करने में अधिक समय लगेगा।

BTW, मूल पोस्ट में अपेक्षित परिणाम गलत है: यह अंत के पास एक "एच" याद कर रहा है।


इंगित करने के लिए जी.डी. संपादित
पचेरियर

3

मेरा पालतू सिद्धांत है कि प्रोग्रामिंग मॉडल कंप्यूटर के वास्तविक कामकाज के करीब होने को समझने में आसान होते हैं। पॉइंटर्स को समझना मुश्किल है जब तक आपको एहसास न हो जाए कि वे अनिवार्य रूप से मशीन एड्रेस हैं। रिकर्सियन को समझना मुश्किल है जब तक कि आपने जानबूझकर एक छोटे से उदाहरण के माध्यम से कदम नहीं उठाया है, स्टैक फ्रेम को देखा है, और महसूस किया है कि एक ही चर के विभिन्न मूल्यों को कहाँ संग्रहीत किया जाता है। इसका मतलब यह नहीं है कि असेंबलर प्रोग्रामिंग उच्च-स्तरीय प्रोग्रामिंग की तुलना में आसान है, लेकिन यह देखा गया है कि यह कैसे किया जाता है यह उस मानसिक मॉडल के लिए चमत्कार करता है जो प्रवीणता के लिए महत्वपूर्ण है - चाहे प्रोग्रामिंग में या सामान्य प्रयोज्य में।

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

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


7
उस तर्क से असेंबलर को सभी भाषाओं को सीखना आसान होना चाहिए :)
होमडे

4
यदि आप सही दिशा से इस पर आते हैं तो कार्यात्मक प्रोग्रामिंग को समझना काफी आसान है। "अमूर्त कार्यात्मक मशीन" जो आप उल्लेख करते हैं वह बस बीजगणित है । मूल्यांकन पुनर्मूल्यांकन द्वारा किया जाता है; समारोह आवेदन प्रतिस्थापन द्वारा किया जाता है। प्रोग्रामर उसी टूल का उपयोग करके समस्याओं को हल करना सीखते हैं जो उन्होंने पहले ही गणित के मामलों में देखा है। यदि वे सीएस का पीछा करते हैं, तो बाद में कछुओं के ढेर को पूरा करने के लिए पर्याप्त समय है; यदि नहीं, तो वे अभी भी उपयोगी समस्या-समाधान कौशल और डिजाइन सिद्धांत सीख चुके हैं। कैसे डिजाइन कार्यक्रम पर एक नज़र रखना ।
रयान कुलपिपर

2
@ एमको नहीं, इस तर्क से वास्तविक बायोटेक 011011001001101...सीखना आसान भाषा होगी!
MarkJ

2
@konrad: RISC कोडांतरक IS शायद सबसे आसान भाषा है। यह जानने के लिए कि इसे कुछ उपयोगी बनाने के लिए एक और कहानी एक साथ है ...
ब्रायन बोएचर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.