कब / क्यों मुझे प्रग्नेंट का उपयोग करना चाहिए?


19

मैंने देखा है prognकाफी एक बहुत इस्तेमाल किया जा रहा के रूप में मैं अनुभवी Emacs प्रयोक्ताओं की विन्यास फाइल ब्राउज़ करें। मुझे इसकी अच्छी व्याख्याprogn मिली , लेकिन मैं वास्तव में उत्सुक हूं कि इस फ़ंक्शन का उपयोग करने का क्या लाभ है? इस स्निपेट का उदाहरण लें ( सच्चा चुआ के विन्यास से लिया गया ):

(use-package undo-tree
  :defer t
  :ensure t
  :diminish undo-tree-mode
  :config
  (progn
    (global-undo-tree-mode)
    (setq undo-tree-visualizer-timestamps t)
    (setq undo-tree-visualizer-diff t)))

क्या उपरोक्त विन्यास और इसके बीच कोई बड़ा अंतर है?

(use-package undo-tree
  :defer t
  :ensure t
  :diminish undo-tree-mode
  :config
  (global-undo-tree-mode)
  (setq undo-tree-visualizer-timestamps t)
  (setq undo-tree-visualizer-diff t))

मुझे लगता है कि पहला उदाहरण किसी तरह क्लीनर है, भले ही इसमें अधिक सिंटैक्स हो, और मेरा अंतर्ज्ञान यह है कि उपयोग करने से किसी प्रकार का प्रदर्शन बढ़ सकता है progn, लेकिन मुझे यकीन नहीं है। किसी भी अंतर्दृष्टि के लिए धन्यवाद!


7
इस विशेष मामले में कोई अंतर नहीं है: use-packageएक लपेटो जाएगा prognअपने चारों ओर: config रूपों अगर यह याद आ रही है। इसे आज़माएं: आप बिंदु को अंत में रख सकते हैं (use-package ...)और कॉल M-x pp-macroexpand-last-sexpकर सकते हैं कि मैक्रो का विस्तार कैसे किया जाता है। आप देखेंगे कि यह इन दो उदाहरणों के लिए समान है।
ग्लूकोज

एक उदाहरण जहां prognआवश्यक है: emacs.stackexchange.com/questions/39172/…
npostavs

जवाबों:


11

prognआम तौर पर मैक्रोज़ के साथ काम करते समय उपयोग किया जाता है। कुछ मैक्रोज़ ( use-packageएक मैक्रो, अंतिम मैंने जाँच की) केवल 1 फॉर्म स्वीकार करते हैं , जहां अन्य सभी शेष रूपों का उपभोग करते हैं

progn पूर्व के मामले में प्रपत्रों के अनुक्रम को एकल रूप में बदलने के लिए उपयोग किया जाता है।

आपके उदाहरणों में, पहले वाला उपयोग करता है prognऔर इस प्रकार 1 के बाद फॉर्म है:config । दूसरे में, 3 रूप हैं । यदि use-packageमैक्रो केवल 1 फॉर्म का अनुसरण करने की उम्मीद करता है :config, तो यह एक त्रुटि का कारण होगा।

यह ध्यान देने योग्य है कि prognदोनों मामलों में काम का उपयोग करना, जबकि इसे छोड़ना केवल तभी काम करता है जब मैक्रो कई रूपों को स्वीकार करता है। इसके परिणामस्वरूप, कुछ लोग बस हमेशा उपयोग करना पसंद करते हैं progn, क्योंकि यह हमेशा काम करेगा।


15
इसका वास्तव में मैक्रोज़ से कोई लेना-देना नहीं है। कुछ कार्यों और मैक्रोज़ में एक तथाकथित "निहित progn" होता है, जिसका अर्थ है कि वे किसी भी संख्या में सेक्स को अलग-अलग तर्क के रूप में स्वीकार करते हैं और उन्हें अनुक्रम में मूल्यांकन करते हैं। अन्य नहीं करते हैं, और इसके बजाय केवल एक ही तर्क की अपेक्षा / अनुमति देते हैं जहां आप अनुक्रम में कई लिंगों का मूल्यांकन करना चाहते हैं। यह सब prognकरता है: यह आपको एक सिंगल सेक्सप्लस प्रदान करता है, जब मूल्यांकन किया जाता है कि सीक्वेंस में सेक्सपी आरजीएस का मूल्यांकन करता है progn। तुलना (if true (progn a b c))के साथ (when true a b c)। दोनों मामलों में a, bऔर, और cअनुक्रम में मूल्यांकन किया जाता है।
ड्रू


4
मैं इस बात से असहमत हूं कि उपयोग के मामलों में से 99% मैक्रोज़ आदि के लिए हैं। किसी भी फ़ंक्शन या मैक्रो को एक prognसेक्सप पास किया जा सकता है जिसमें कई सेक्सप्लस शामिल हैं, जो कि उनके दुष्प्रभावों के लिए मूल्यांकन किए जाते हैं, इनमें से अंतिम परिणाम वापस करने से पहले। इसका वास्तव में मैक्रोज़ से कोई लेना-देना नहीं है। मैक्रोज़ "एक उदाहरण के रूप में" ठीक है। prognमैक्रोज़ के लिए मौजूद धारणा को देते हुए , और इसका 99% उपयोग मैक्रोज़ के लिए है, भ्रामक है, आईएमओ। एक एकल सेक्सप में मूल्यांकन के prognएक अनुक्रम को दूर करने के बारे में है (किसी दिए गए अपेक्षित तर्क को फिट करने के लिए), और इसलिए यह दुष्प्रभावों के बारे में है
आकर्षित किया

5
1. लिस्प 1.5progn में पेश किया गया था (अनुभाग देखें कार्यक्रम फ़ीचर ), 1962 में, मैक्रो को लिस्प में जोड़े जाने से बहुत पहले। उद्देश्य क्रमिक रूप से उनके दुष्प्रभावों के लिए भावों का मूल्यांकन करना है। 2. देखें कि कैसे Emacs खुद Elisp प्रोग्रामर्स से मिलवाता है। एक साधारण उपयोग के मामले के लिए कोड देखें । prognprognzap-to-char
आकर्षित किया

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

10

सबसे महत्वपूर्ण कारण progn की पहली पंक्ति में वर्णन किया गया है progn प्रलेखन (जोर जोड़ा):

प्रोग्न एक विशेष रूप है जो इसके प्रत्येक तर्क को अनुक्रम में मूल्यांकन करने का कारण बनता है और फिर पिछले एक का मान लौटाता है।

परिशिष्ट:

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

अंतर्निहित नियंत्रण संरचनाएं विशेष रूप हैं क्योंकि उनके उपरूपों का मूल्यांकन आवश्यक नहीं है या क्रमिक रूप से मूल्यांकन नहीं किया गया है

क्या प्रग्नेंस परफॉर्मेंस बढ़ाता है?

पार्सिंग प्रदर्शन, नहीं। निष्पादन प्रदर्शन, नहीं। सबसे अच्छा यह बराबर हो सकता है लेकिन कभी भी जादुई रूप से प्रदर्शन को बढ़ावा नहीं देता है।

जब है progn इस्तेमाल किया ?

... सबसे अधिक बार एक अंदर खोलना-रक्षित, और, या , या एक के तत्कालीन भाग में यदि


मुझे यकीन नहीं है कि यह इतना महत्वपूर्ण क्यों है। Emacs हमेशा क्रमिक रूप से मूल्यांकन करता है।
चंद्रग्रहण

2
@lunaryorn अद्यतन किया गया उत्तर देखें।
Emacs उपयोगकर्ता

मुझे यकीन नहीं है कि मैं आपके संपादन को समझ पा रहा हूं। स्वाभाविक रूप से एक अलग मूल्यांकन क्रम (जैसे if) के साथ विशेष रूप होते हैं , लेकिन सामान्य मूल्यांकन क्रम (जैसे शीर्ष स्तर के रूप, कार्य निकाय, आदि) पाठ है। ज़रूर, कुछ हद तक यह एक निहित है progn, लेकिन यह आमतौर पर वह नहीं है जो आप progn अपने कोड में उपयोग करते हैं।
चंद्ररात्रि

मुझे लगता है कि एलिफ़िश मैनुअल नोड (elisp) Sequencingजिसे आप लिंक करते हैं, यह सब कहता है।
तुलसी १

10

prognपरिवार के साथ तुलना करके यह समझने का एक बेहतर तरीका है : prog1और prog2। नाम का nया 1या 2भाग उस सूची से बयान के लिए खड़ा है जिसका परिणाम आप में रुचि रखते हैं। दूसरे शब्दों prognमें, इसमें शामिल अंतिम कथन का परिणाम prog1वापस आ जाएगा , जबकि पहले वापस आ जाएगा, और इसी तरह के लिए prog2

आज यह कार्यक्षमता थोड़ी अजीब लग रही है क्योंकि हम या तो कार्यक्रम को अंतिम विवरण में लौटने की उम्मीद करना सीख रहे हैं, या यह स्पष्ट रूप से निर्देश देने के लिए कि क्या लौटना है। इस प्रकार prog1और prog2शायद ही कभी इस्तेमाल किया जाता है। हालाँकि, अगर आप इसके बारे में सोचते हैं, तो यह समझ में आता है, और यहाँ है:

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

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

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