"और" बनाम "जब" सशर्त के लिए


13

यह इस उत्तर पर टिप्पणियों का अनुसरण है । कोड के निम्नलिखित बिट समतुल्य प्रतीत होते हैं:

(and a b)

(when a b)

बेशक andआपको और अधिक शर्तें लगाने देता है: (and a b c d)साधन(when (and a b c) d)

मैं whenकेवल ब्रांचिंग को व्यक्त करने के लिए उपयोग करता हूं । क्या वास्तविक अंतर हैं? क्या एक या दूसरे का उपयोग करना बेहतर है?

मेरे पास हाथ में एमएसीएस का स्रोत नहीं है; andएक सी फ़ंक्शन है; whenएक मैक्रो है जो विस्तार करता है if, जो स्वयं एक सी फ़ंक्शन है।


"बेशक और देता है" होना चाहिए "बेशक` और `देता है", लेकिन यह केवल एक 2 चरित्र परिवर्तन है और एक अनुमति संपादित नहीं है। कोई ओवरराइड नहीं है।
हार्वे

जवाबों:


18

टीएल; डीआर: when दुष्प्रभाव के बारे में andहै, शुद्ध बूलियन अभिव्यक्तियों के लिए है।

जैसा कि आपने देखा है, andऔर whenकेवल सिंटैक्स में भिन्न है, लेकिन अन्यथा पूरी तरह से समकक्ष हैं।

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

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

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

इसलिए, के बीच वास्तविक अंतर andऔर whenशैलीगत है: आप andशुद्ध बूलियन अभिव्यक्तियों के लिए उपयोग करते हैं, और whenसाइड-इफेक्टिंग रूपों के चारों ओर एक गार्ड लगाने के लिए।

इसलिए, ये खराब शैली हैं:

;; `when' used for a pure boolean expression
(let ((use-buffer (when (buffer-live-p buffer)
                    (file-exists-p (buffer-file-name buffer)))))
  ...)

;; `and' used as guard around a side-effecting form
(and (buffer-file-name buffer) (write-region nil nil (buffer-file-name buffer)))

और ये अच्छे हैं:

(let ((use-buffer (and (buffer-live-p buffer)
                       (file-exists-p (buffer-file-name buffer)))))
  ...)

(when (buffer-file-name buffer)
 (write-region nil nil (buffer-file-name buffer)))

मुझे पता है कि कुछ लोग इस बारे में असहमत हैं, और खुशी से andसाइड-इफ़ेक्ट का उपयोग करते हैं, लेकिन मुझे लगता है कि यह वास्तव में खराब शैली है। हमारे पास एक कारण के लिए ये विभिन्न रूप हैं: सिंटैक्स मायने रखता है । यदि ऐसा नहीं होता है, तो हम केवल कभी भी उपयोग करेंगे if, जो केवल सशर्त रूप से आपको Emacs Lisp शब्दार्थ में आवश्यक है। अन्य सभी बूलियन और सशर्त रूपों के संदर्भ में लिखा जा सकता है if


2
IMO (यानी, मेरे द्वारा उपयोग की जाने वाली शैली में), वापसी मूल्य के बारेand में देखभाल करने के बारे में है । यह जरूरी नहीं कि साइड इफेक्ट का उपयोग करने के बारे में नहीं है। यदि मेरा प्रोग्राम रिटर्न वैल्यू की परवाह करता है तो मैं उपयोग करता हूं and। अगर यह नहीं होता है तो मैं उपयोग करता हूं when। IOW, मैं when केवल साइड इफेक्ट्स के लिए उपयोग करता हूं , लेकिन मैं एक prognमें से एक में अच्छी तरह से उपयोग कर सकता हूं and। यह इस बारे में है कि क्या वापसी मूल्य मायने रखता है, इस बारे में नहीं कि क्या यह अकेले मायने रखता है।
आकर्षित किया

5
andमुझे पता है कि किसी भी लिस्प में एक समारोह नहीं है। Emacs Lisp में यह एक विशेष रूप है, कॉमन लिस्प में यह एक मैक्रो है, केवल इसलिए कि इसमें शॉर्ट-सर्किट व्यवहार (कार्यों के साथ असंभव है, क्योंकि वे हमेशा उनके तर्कों का मूल्यांकन करते हैं) की उम्मीद है।
मार्क कार्पोव

2
@lunaryorn, हाँ, यह वास्तव में प्रासंगिक नहीं है, लेकिन यह सच है, इसलिए मुझे लगता है कि यह लिखना गलत है कि andयह एक फ़ंक्शन है, जब यह नहीं है। इससे कोई फर्क नहीं पड़ता कि प्रश्न के लिए तथ्य कितना प्रासंगिक है, हमें हमेशा सही शब्दों का उपयोग करना चाहिए, बस।
मार्क कार्पोव

2
खैर, मुझे नहीं लगता कि "हर तर्क फॉर्म का मूल्य महत्वपूर्ण है" उस व्याख्या के अनुरूप है। यह कहकर बेहतर व्यक्त किया जा सकता था कि किसी भी रूप का मूल्यांकन केवल उसके मूल्य को फेंकने के लिए नहीं किया जाता है।
हेराल्ड हैन्च-ऑलसेन

3
कुछ हद तक ओटी, लेकिन: यह अंतर लिसप्स में शैलीगत से अधिक है जो nil"झूठे", "खाली सूची", "शून्य" आदि के सभी अर्थों को इंगित नहीं करता है , उदाहरण के लिए स्कीम और गैर-सत्य परिणाम के रैकेट whenहै void(अर्थात "कोई अर्थ नहीं") जबकि andयह #f("असत्य") है। हालांकि यह एल / एस्प के लिए एन / ए है, यह एक लिस्प जनरलिस्ट पर विचार कर सकता है।
ग्रेग Hendershott

4

मुझे यह कहकर शुरू करें कि (and a b)और (when a b)आपके उदाहरण में एक ही काम करें: पहले aमूल्यांकन किया जाता है। bयदि मूल्यांकन किया जाता है aहै सच #

लेकिन and और whenविभिन्न चीजों के लिए उपयोग किया जाता है।

  • आप का प्रयोग करेंगे (and a b)वापस जाने के लिए सच # अगर दोनों aऔर bकर रहे हैं सच # (या गैर शून्य); और nilअन्यथा।

  • आप उपयोग करेंगे (when a b)या अधिक सही होंगे,

    (when a
       ;; do something like b
       )

    जब आप "b" कोड को निष्पादित करना चाहते हैं, यदि केवल और यदि # सचa है तो ।


यहाँ एक उदाहरण है जहाँ आप उपयोग करते हैं whenऔर andएक साथ:

(when (and a b)
   (do-c))

इन सबसे ऊपर, समारोह do-cपर ही कहा जाता है aऔर bकर रहे हैं सच #


अध्ययन के लिए संदर्भ

# के लिए सभी संदर्भ सच बूलियन सही का संदर्भ लें।


3
andtयदि इसके सभी तर्क गैर-शून्य हैं, लेकिन अंतिम तर्क का मान नहीं लौटाता है।
सार्थक यूजरनेम

1
द्वारा t, मेरा मतलब था बूलियन ट्रू या नॉन-नील। धन्यवाद, मैं अपने उत्तर में स्पष्ट करूंगा।
कौशल मोदी

मुझे नहीं लगता कि आपका जवाब बहुत आगे जाता है कि मैंने पहले ही प्रश्न में क्या कहा था; मुझे पता है कि दोनों क्या करते हैं, और अंतिम उदाहरण जो आप पहले से ही देते हैं वह मेरे प्रश्न ( (when (and a b) c)) में दिखाई देता है । इसके अलावा, यह कैसे andऔर whenकिसके बारे में सुझाव देता है कि वास्तव में वे सामान्य रूप से कैसे उपयोग किए जाते हैं, लेकिन इस प्रश्न का बहुत आधार यह तथ्य था कि मैं अक्सर उन्हें अलग-अलग तरीके से उपयोग करते देखता हूं (उदाहरण के लिए उत्तर मैं अपने प्रश्न में जुड़ा हुआ हूं)।
क्लेमेंट

एक पूरी तरह कार्यात्मक निर्माण पॉइंट-ऑफ-देखने के लिए, से जब गैर समाप्त मूल्यांकन के लिए है और और प्रत्यक्ष प्रतीकों और बूलियन तर्क के लिए है। कार्यात्मक प्रोग्रामिंग को इस अंतर की आवश्यकता है; जरूरी प्रोग्रामिंग ने इसे दूर कर दिया।
Emacs उपयोगकर्ता

1
मुझे नहीं लगता कि "बूलियन सच" सिर्फ "सच" की तुलना में अधिक स्पष्ट है।
यंगफ्रॉग
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.