[Erlang] एलिक्सीर में दो प्रकार के कार्य क्यों हैं?


Answers

मुझे नहीं पता कि यह किसी और के लिए कितना उपयोगी होगा, लेकिन जिस तरह से मैंने अंततः अवधारणा के चारों ओर अपना सिर लपेट लिया था, यह महसूस करना था कि इलीक्सिर फ़ंक्शंस फ़ंक्शंस नहीं हैं।

Elixir में सब कुछ एक अभिव्यक्ति है। इसलिए

MyModule.my_function(foo) 

एक समारोह नहीं है लेकिन अभिव्यक्ति my_function में कोड निष्पादित करके लौटा दी गई है। एक "फ़ंक्शन" प्राप्त करने के लिए वास्तव में केवल एक ही तरीका है जिसे आप एक तर्क के रूप में पारित कर सकते हैं और यह अनाम फ़ंक्शन नोटेशन का उपयोग करना है।

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

यदि आप खुद से पूछते हैं:

क्या मुझे इस स्थान पर निष्पादन वातावरण या डेटा मान की आवश्यकता है?

और यदि आपको निष्पादन का उपयोग एफएन की आवश्यकता है, तो अधिकांश कठिनाइयों को बहुत स्पष्ट हो जाता है।

Question

मैं इलीक्सिर सीख रहा हूं और आश्चर्य करता हूं कि इसमें दो प्रकार की फ़ंक्शन परिभाषाएं क्यों हैं:

  • def साथ एक मॉड्यूल में परिभाषित कार्यों, myfunction(param1, param2) का उपयोग कहा जाता है
  • अज्ञात कार्यों को fn साथ परिभाषित किया गया है, जिसे myfn.(param1, param2) का उपयोग कहा जाता है myfn.(param1, param2)

केवल दूसरा प्रकार का कार्य प्रथम श्रेणी की वस्तु प्रतीत होता है और इसे अन्य कार्यों के पैरामीटर के रूप में पारित किया जा सकता है। एक मॉड्यूल में परिभाषित एक समारोह को एक fn में लपेटा जाना चाहिए। कुछ otherfunction(myfunction(&1, &2)) चीनी है जो इसे आसान बनाने के लिए अन्य otherfunction(myfunction(&1, &2)) की तरह otherfunction(myfunction(&1, &2)) है, लेकिन यह पहली जगह क्यों जरूरी है? हम सिर्फ अन्य कार्य क्यों नहीं कर सकते otherfunction(myfunction)) ? क्या यह केवल रूबी जैसे ब्रांड्स के बिना कॉलिंग मॉड्यूल फ़ंक्शंस को अनुमति देने के लिए है? ऐसा लगता है कि इस विशेषता को एरलांग से विरासत में मिला है जिसमें मॉड्यूल फ़ंक्शंस और मज़े भी हैं, तो क्या वास्तव में यह वास्तव में आता है कि एरलांग वीएम आंतरिक रूप से कैसे काम करता है?

यह दो प्रकार के कार्यों के साथ कोई लाभ है और उन्हें अन्य कार्यों में पारित करने के लिए एक प्रकार से दूसरे में परिवर्तित करना है? क्या कॉल करने के लिए दो अलग-अलग नोटेशन होने का कोई लाभ है?




मैंने कभी नहीं समझा है कि इसका स्पष्टीकरण इतना जटिल क्यों है।

यह वास्तव में रूबी शैली "माता-पिता के बिना फ़ंक्शन निष्पादन" की वास्तविकताओं के साथ संयुक्त रूप से असाधारण रूप से छोटा अंतर है।

की तुलना करें:

def fun1(x, y) do
  x + y
end

सेवा मेरे:

fun2 = fn
  x, y -> x + y
end

हालांकि ये दोनों पहचानकर्ता हैं ...

  • fun1 एक पहचानकर्ता है जो fun1 साथ परिभाषित नामित फ़ंक्शन का वर्णन करता है।
  • fun2 एक पहचानकर्ता है जो एक चर का वर्णन करता है (जो फ़ंक्शन के संदर्भ में होता है)।

गौर करें कि इसका मतलब क्या है जब आप किसी अन्य अभिव्यक्ति में fun1 या fun2 देखते हैं? उस अभिव्यक्ति का मूल्यांकन करते समय, क्या आप संदर्भित फ़ंक्शन को कॉल करते हैं या आप केवल स्मृति के मान को संदर्भित करते हैं?

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

और यह वास्तव में मुश्किल है। कल्पना कीजिए कि एक बिंदु नोटेशन नहीं था। इस कोड पर विचार करें:

val = 5

if :rand.uniform < 0.5 do
  val = fn -> 5 end
end

IO.puts val     # Does this work?
IO.puts val.()  # Or maybe this?

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




केवल दूसरा प्रकार का कार्य प्रथम श्रेणी की वस्तु प्रतीत होता है और इसे अन्य कार्यों के पैरामीटर के रूप में पारित किया जा सकता है। एक मॉड्यूल में परिभाषित एक समारोह को एक एफएन में लपेटा जाना चाहिए। कुछ otherfunction(myfunction(&1, &2)) चीनी है जो इसे आसान बनाने के लिए अन्य otherfunction(myfunction(&1, &2)) की तरह otherfunction(myfunction(&1, &2)) है, लेकिन यह पहली जगह क्यों जरूरी है? हम सिर्फ अन्य कार्य क्यों नहीं कर सकते otherfunction(myfunction)) ?

आप अन्य कार्य कर सकते हैं otherfunction(&myfunction/2)

चूंकि elixir ब्रैकेट (जैसे myfunction ) के बिना फ़ंक्शंस निष्पादित कर सकता है, अन्य कार्य ( myfunction ) का उपयोग करके otherfunction(myfunction)) यह myfunction/0 निष्पादित करने का प्रयास करेगा।

इसलिए, आपको कैप्चर ऑपरेटर का उपयोग करने और धैर्य समेत फ़ंक्शन निर्दिष्ट करने की आवश्यकता है, क्योंकि आपके पास एक ही नाम के साथ अलग-अलग फ़ंक्शन हो सकते हैं। इस प्रकार, &myfunction/2




Links