क्या आप C में कार्यात्मक प्रोग्रामिंग सीख सकते हैं? [बन्द है]


9

यहाँ टिप्पणी चर्चा के परिणामस्वरूप , मुझे आश्चर्य है कि क्या आप C में कार्यात्मक प्रोग्रामिंग सीख सकते हैं?


30
आप कर सकते हैं या नहीं, इसके बारे में परवाह नहीं है
आर। मार्टिनो फर्नांडीस

27
पूर्ण रूप से! पहला कदम एक लिस्प दुभाषिया ;-) लिखना है
फेरुचियो 10

अगर मुझे यह सही लगता है, तो सवाल किसी भी वास्तविक भाषा के बिना, स्यूडोकोड के साथ विभिन्न अवधारणाओं को सीखने के बारे में होना चाहिए था ।
एसके-तर्क

@ एसके-तर्क: इसे हल्के से कहने के लिए, बहुत कम प्रोग्रामर ने शुद्ध रूप से छद्म कोड के साथ प्रोग्रामिंग सीखी है, अधिकांश को अपने हाथों को गंदा करना पड़ा और उनके चेहरे को कंपाइलर / दुभाषिया से त्रुटि संदेशों के साथ स्मैक दिया गया।
sbi

4
@sbi, कुछ बेहतरीन प्रोग्रामर्स ने प्रोग्रामिंग सीखी है जब कंपाइलर्स में कोई त्रुटि संदेश नहीं था। पंच कार्ड पर कोडिंग करने से आपको कोड को चलाने का मौका मिलने से बहुत पहले समझने की आवश्यकता होती है। और यह उल्लेख करने की आवश्यकता नहीं है कि पहले कंप्यूटर के निर्माण से बहुत पहले कार्यात्मक प्रोग्रामिंग के लिए आधार स्थापित किया गया था।
तर्क

जवाबों:


21

जाहिर है आप सी में कार्यात्मक प्रोग्रामिंग कर सकते हैं । सिद्धांत रूप में, आप सी में कार्यात्मक प्रोग्रामिंग सिद्धांत भी सीख सकते हैं , लेकिन भाषा इसे आसान नहीं बनाती है।

मुझे लगता है कि आपके पास OOP में कम से कम एक पृष्ठभूमि है; यदि आप करते हैं, तो आपको पता होना चाहिए कि OOP C में किया जा सकता है, जिसमें बहुरूपता, गेटर्स / सेटर, दृश्यता नियम आदि शामिल हैं, लेकिन ऐसा करने के लिए काफी दर्दनाक है, और आपको OOP और C दोनों को अंदर जानना होगा। इसे बाहर खींचने के लिए। एफपी के साथ भी ऐसा ही है।

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


अनुरोध के अनुसार, कुछ चीजें जो आप FP से सीख सकते हैं और फिर C, C ++ या Java में लागू कर सकते हैं:

  • राज्य से बचें, विशेष रूप से साझा उत्परिवर्तित अवस्था
  • शुद्ध कार्यों की सराहना करते हैं
  • आलसी मूल्यांकन की सराहना करें
  • संज्ञा के बजाय क्रिया के संदर्भ में मॉडल करने में सक्षम होना
  • पुनरावृत्ति के साथ-साथ पुनरावृत्ति से होने वाली समस्याओं के लिए सक्षम होने के नाते
  • उच्च-क्रम के कार्यों का उपयोग करना
  • फ़ंक्शंस के बारे में सिर्फ एक अन्य प्रकार के मूल्य के बारे में सोचकर, कि आप चारों ओर से गुजर सकते हैं और अन्य मूल्यों के साथ संयोजन कर सकते हैं
  • ऑब्जेक्ट-आधारित बहुरूपता के विकल्प के रूप में प्रथम श्रेणी के कार्यों का उपयोग करना

1
क्या आप विशिष्ट उदाहरण प्रदान कर सकते हैं कि कैसे C / C ++ / Java प्रोग्रामर LISP ज्ञान से लाभ उठा सकते हैं। यह सिद्धांत में समझ में आता है, लेकिन मैं कुछ ठोस तलाश रहा हूं।
अय्यूब

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

तो क्या मैं इससे यह निष्कर्ष निकाल सकता हूं, जबकि C में यह (कुछ) FP सीखना संभव है, ऐसा करने का कोई मतलब नहीं है?
sbi

@ जोब: मैंने एफपी सीखा है जब मैंने कई साल पहले एक छात्र के रूप में एलआईएसपी सीखा था। लगभग एक दशक बाद मैंने टेम्पलेट मेटा-प्रोग्रामिंग में एफपी लागू किया।
sbi

1
@sbi, नई भाषाओं और अवधारणाओं को सीखने का मेरा पसंदीदा तरीका उन्हें लागू करना है। और सी एक संकलक को लागू करने के लिए काफी सभ्य भाषा है। तो, हाँ, आप एफपी सी के साथ सीख सकते हैं
SK-तर्क

11

C को कुछ कार्यात्मक अवधारणाओं की पेशकश करने के लिए हैक किया जा सकता है:

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

वास्तव में कार्यात्मक प्रोग्रामिंग सीखने के लिए आपका सबसे अच्छा दांव लिस्प और इसकी बोलियों ( क्लोजर , स्कीम ), एर्लैंग और हास्केल जैसी प्रमुख कार्यात्मक प्रोग्रामिंग भाषाओं में से एक है । उनमें से कोई भी सही उपकरण हैं जो कार्यात्मक प्रोग्रामिंग मानसिकता के भीतर काम करते हैं। यदि आपके पास .Net पृष्ठभूमि है, तो F # भी एक अच्छा उम्मीदवार है, लेकिन यह एक बहु प्रतिमान भाषा है, कड़ाई से कार्यात्मक प्रोग्रामिंग भाषा नहीं है।


टिप्पणी में tdammers नोट के रूप में:

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

मेरे ज्ञान का सबसे अच्छा करने के लिए लिस्प और इसकी बोलियाँ और एर्लैंग एफ # से बेहतर उम्मीदवार हैं क्योंकि वे अन्य प्रतिमानों पर कार्यात्मक प्रोग्रामिंग को प्रोत्साहित करते हैं, जो टैडमर्स खूबसूरती से भाषा के शुरुआती बिंदु के रूप में बताता है । एफ # कार्यात्मक प्रोग्रामिंग को शामिल नहीं करता है, लेकिन इसके अन्य समर्थित प्रतिमानों, अनिवार्य और ऊ प्रोग्रामिंग पर इसे प्रोत्साहित नहीं करता है।


आपके अंतिम वाक्य के बारे में: उस स्थिति में मैं तर्क दूंगा कि F # एक बेहतर उम्मीदवार है क्योंकि यह आपको एक कार्यात्मक मानसिकता में नहीं फँसाएगा। बहु-प्रतिमान भाषा में, जब आप शिकंजा कसना शुरू करते हैं, तो आप बस एक पेचकश पर स्विच कर सकते हैं। जब आप एक ही प्रतिमान में फंस जाते हैं, तो आप पेंच और नाखून के बीच का अंतर याद कर सकते हैं।
आर। मार्टिनो फर्नांडिस

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

मेरा मानना ​​है कि सीखना जब प्रतिमान अच्छी तरह से अनुकूल होता है और जब यह एक निश्चित कार्य के लिए बीमार होता है तो यह सीखने का एक हिस्सा है, शायद सबसे महत्वपूर्ण।
आर। मार्टिनो फर्नांडिस

4
दरअसल, LISP, क्लोजर और स्कीम भी बहु प्रतिमान हैं; हास्केल, शुद्ध और डिफ़ॉल्ट-आलसी होने के साथ-साथ एक उन्मादी संदर्भ में भी अनिवार्य प्रोग्रामिंग की अनुमति देता है, और इसमें समवर्ती प्रसंस्करण के लिए व्यापक समर्थन है। इन सभी में ऐसे तंत्र हैं जो ओओपी दुनिया में इकट्ठा किए गए ज्ञान के बड़े हिस्से को लागू करते हैं - इनकैप्सुलेशन, इनहेरिटेंस, सिंगल-जिम्मेदारी, कंपोजिशन, आदि। यह इतना नहीं है कि क्या एक भाषा अन्य प्रतिमानों के बारे में; यह इस बारे में है कि कौन सा प्रतिमान भाषा के शुरुआती बिंदु बनाता है।
tdammers

2
@MartinhoFernandes: कोई यह तर्क दे सकता है कि किसी एकल प्रतिमान में फंसने से यह सीखने का सही तरीका है कि यह वास्तव में गधे में दर्द है या नहीं
Jörg W Mittag

2

आप सी में कार्यात्मक प्रोग्रामिंग के सभी पहलुओं को नहीं सीख सकते हैं लेकिन निश्चित रूप से आप किसी भी अनिवार्य भाषा के साथ कार्यात्मक शैली प्रोग्रामिंग शुरू कर सकते हैं। ये शुरुआती बिट्स हैं- "प्रोग्रामिंग करते समय चीजों को शुद्ध कैसे रखें।" और इसे C भी किया जा सकता है। विवरण के लिए इस ब्लॉग पोस्ट की जाँच करें-

http://www.johndcook.com/blog/2011/07/24/get-started-functional-programming/


2

टी एल; डॉ

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

कार्यात्मक प्रोग्रामिंग क्या है?

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

क्लोजर उपयोगिता के तीन चित्र

क्लोजर का एक विशिष्ट उपयोग गोपनीयता तंत्र का कार्यान्वयन है। उदाहरण के लिए जावास्क्रिप्ट कोड - उदाहरणों में मैंने जावास्क्रिप्ट को चुना क्योंकि यह एक कार्यात्मक भाषा है जिसमें तथाकथित "सी-जैसे सिंटैक्स" है और आपका प्रश्न बताता है कि आप सी से परिचित हैं:

create_counter = function()
{
  var x = 0;
  var counter = function()
  {
    ++x;
    return x;
  };
  return counter;
}

फिर साथ में

a = create_counter();
b = create_counter();

हमारे पास दो कार्य हैं aऔर bगणना संग्रह की गणना कर रहे हैं। उदाहरण की बात यह है कि xक्लोजर को बंद करने से चर को पकड़ लिया जाता है counterऔर हर बार एक नया counterक्लोजर is instantiated by the function, it gets its fresh own idea of whatx` होता है।

क्लोजर का एक और विशिष्ट उपयोग कार्यों के आंशिक अनुप्रयोगों की परिभाषा है। मान लें कि हमारे पास syslogएक फ़ंक्शन लागू करने के समान रिपोर्टिंग सुविधा है

var log = function(priority, message) {

};

जहां तर्क priorityऔर messageतार होने की उम्मीद है, पहले एक से एक होने "debug", "info", और इतने पर। हम इस तरह एक लॉग फैक्टरी को परिभाषित कर सकते हैं:

var logWithPriority = function(priority) {
  return function(message) {
    log(priority, message);
  };
};

और इसका उपयोग हमारी लॉग सुविधा के विशेष संस्करणों को परिभाषित करने के लिए करें:

var debug = logWithPriority("debug");
var info = logWithPriority("info");

यह बहुत उपयोगी है, क्योंकि forइस तरह त्रुटि-प्रवण- लूप लिखने के बजाय

for(i = 0; i < journal.length; ++i) {
   log("info", journal[i]);
}

हम क्लीनर, छोटे और बहुत सरल लिख सकते हैं (कोई नहीं है i, यह बहुत बेहतर है):

journal.forEach(logWithPriority("info"));

क्लोजर का एक तीसरा महत्वपूर्ण अनुप्रयोग क्षेत्र आलसी मूल्यांकन का कार्यान्वयन है - ध्यान दें कि बेहतर कार्यान्वयन के लिए विशेष भाषा समर्थन प्रदान कर सकता है।

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

यहाँ क्लोज़र के साथ आलसी मूल्यांकन को कैसे लागू किया जाए। सरणी में अधिकतम लौटने वाले arrayMax फ़ंक्शन के शास्त्रीय कार्यान्वयन पर विचार करें :

function arrayMax(array) {
  return array.reduce(function(a, b) {
    return Math.min(a, b);
  };
}

आलसी संस्करण होगा:

function arrayMax(array) {
  var memo = null;
  function actuallyCompute() {
    if(memo === null) {
      memo = array.reduce(function(a, b) {
        return Math.min(a, b);
      });
    }
    return memo;
  }
  return actuallyCompute;
}

लौटाया गया मान एक क्लोजर है जिसका उपयोग मूल्य की गणना करने के लिए किया जा सकता है या इसे दूसरी बार पुनः प्राप्त किया जा सकता है यदि यह पहले से ही गणना कर चुका हो।

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

निष्कर्ष

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


1
इस अच्छे नमूने के लिए धन्यवाद। BTW, जैसा कि आप var जानकारी को परिभाषित करते हैं, क्या यह journal.forEach (जानकारी) नहीं होगा?
ईजेनेव

हाँ, यह एक उपयुक्त संस्करण होगा! :)
माइकल ले बारबियर ग्रुएनवाल्ड 20

1

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

लेकिन यह वैसे भी अकादमिक है, क्योंकि, जैसा कि मार्टिनहो ने अपनी टिप्पणी में कहा है , भले ही आप कार्यात्मक प्रोग्रामिंग सीख सकें , आपको ऐसा करने की कोशिश नहीं करनी चाहिए , क्योंकि ऐसी भाषाएं हैं जहां यह बहुत आसान है।


1

आपको C में कार्यात्मक प्रोग्रामिंग नहीं सीखनी चाहिए, लेकिन एक सख्त कार्यात्मक भाषा में (हास्केल, कैमल, एर्लांग, आदि।)।)।

यदि आप कार्यात्मक हैं, तो आप वास्तव में एक गैर-कार्यात्मक भाषा के साथ कभी नहीं मिलेंगे। अधिक संभावना है, आप खुद को ऐसा करने के लिए प्रशिक्षित करेंगे जो आपको लगता है कि कार्यात्मक प्रोग्रामिंग है और चीजों को गलत तरीके से सीखते हैं। और यह हमेशा के लिए कठिन है «relearn» चीजों की तुलना में सही तरीके से उन्हें पहली बार में सही तरीका सीखा है।

वैसे भी, मुझे लगता है कि सी में कार्यात्मक करना किसी ऐसे व्यक्ति के लिए एक अच्छा व्यायाम है जो पहले से ही कार्यात्मक जानता है। क्योंकि वह व्यक्ति सीखेगा कि हुड के पीछे क्या चल रहा है - कंप्यूटर वास्तव में क्या कर रहा है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.