फ़ंक्शन के अंत में लिस्प समुदाय सभी कोष्ठकों को संचित करना क्यों पसंद करता है?


26

लिस्प समुदाय समारोह के अंत में सभी कोष्ठकों को संचित करना क्यों पसंद करता है:

(defn defer-expensive [cheap expensive]
  (if-let [good-enough (force cheap)]
    good-enough
    (force expensive)))

सी या जावा जैसे सम्मेलन को क्यों नहीं नियोजित किया जाता है?
ठीक है, लिस्प उन भाषाओं की तुलना में बहुत पुराना है, लेकिन मैं समकालीन लिस्पर्स के बारे में बात कर रहा हूं।

(defn defer-expensive [cheap expensive]
  (if-let [good-enough (force cheap)]
    good-enough
    (force expensive)
  )
)

नोट: कोड स्निपेट "द जॉय ऑफ क्लोजर" पुस्तक से है।


13
मुझे बताया गया है कि पंच कार्डों के दिनों में, एक अतिरिक्त कार्ड के साथ लिस्प प्रोग्राम को समाप्त करना आम बात थी, इस पर 80 सही कोष्ठक थे, बस यह सुनिश्चित करने के लिए कि कार्यक्रम में सभी खुले कोष्ठकों के मिलान के लिए पर्याप्त थे ।
अल्जीरिया

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

5
क्योंकि वे कर सकते हैं?
मुअदिब

यह अच्छा होगा यदि क्लोजर की एक बोली ने कोड संरचना होने के लिए इंडेंटेशन को बढ़ावा दिया। यह पूरी तरह से कोष्ठक के साथ दूर होगा (जैसे एफ #, आदि ..)। यदि वांछित है, तो निश्चित रूप से, कोष्ठक कानूनी होगा।
इंट्रेपिडिस

जवाबों:


28

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

if (pred)
{
  printf("yes");
}

ब्रेसिज़ के भीतर एक और बयान जोड़ना आसान है :

if (pred)
{
  printf("yes");
  ++yes_votes;
}

का मूल रूप था

if (pred)
{ printf("yes"); }

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

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

आम लिस्प में, prognफॉर्म एक अपवाद है (जैसा कि उसके भाई बहन हैं):

(progn
  (exp-ignored-return-1)
  (exp-ignored-return-2)
  (exp-taken-return))

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

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

जहाँ वे खोलते हैं, उस इंडेंटेशन की तुलना में कोष्ठकों का समापन बहुत कम होता है। समय में, कोई भी कोष्ठकों की उपेक्षा करना सीखता है और आकार से लिखता और पढ़ता है - जैसा कि पायथन प्रोग्रामर करते हैं। हालाँकि, यह मत करो कि सादृश्य आपको यह सोचने के लिए प्रेरित करेगा कि कोष्ठक को पूरी तरह से हटा देना सार्थक होगा। नहीं, यह एक बहस के लिए सबसे अच्छा बचा है comp.lang.lisp


2
मुझे लगता है कि अंत में जोड़ना दुर्लभ नहीं है, उदाहरण के लिए (let ((var1 expr1) more-bindings-to-be-added) ...), या(list element1 more-elements-to-be-added)
एलेक्सी

14

क्योंकि यह मदद नहीं करता है। हम कोड संरचना दिखाने के लिए इंडेंटेशन का उपयोग करते हैं। यदि हम कोड के अलग ब्लॉक चाहते हैं, तो हम वास्तव में खाली लाइनों का उपयोग करते हैं।

चूंकि लिस्प सिंटैक्स इतना सुसंगत है, इसलिए कोष्ठक प्रोग्रामर और संपादक दोनों के लिए इंडेंटेशन का निश्चित मार्गदर्शक है।

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

बस यह प्रदर्शित करने के लिए कि ये ऑपरेटर सी-जैसी भाषा में उपलब्ध थे:

Foo defer_expensive (Thunk cheap, Thunk expensive) {
    if (Foo good_enough = force (cheap)) {
        return good_enough; }
    else {
        return force (expensive); }}

दो क्लोजिंग ब्रेसेस दो नेस्टिंग स्तरों को बंद करते हैं। वाक्यविन्यास स्पष्ट रूप से सही है। पायथन सिंटैक्स के अनुरूप, ब्रेसिज़ केवल स्पष्ट इंडेंट और डेडेंट टोकन हैं।

बेशक, यह "एक सही ब्रेस स्टाइल" टीएम नहीं हो सकता है , लेकिन मेरा मानना ​​है कि यह सिर्फ ऐतिहासिक दुर्घटना और आदत है।


2
इसके अलावा, लगभग सभी तुतलाना संपादकों मिलान कोष्टक निशान जब (कुछ भी सही बंद करने )के लिए ], या विपरीत उपाध्यक्ष) ताकि आप जानते हैं कि आप सही मात्रा में भले ही आप इंडेंटेशन स्तर की जांच नहीं करते बंद कर दिया।
विन्यासकर्ता

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

1
@ मेसन व्हीलर हां, बिल्कुल।
चिरॉन

3
टीबीएच, जो मुझसे यह कहता है कि एलआईएसपी में परचेस ज्यादातर बेमानी हैं, संभावना के साथ (सी ++ के साथ) कि इंडेंटेशन गलत हो सकता है - अगर इंडेंटेशन आपको बताता है कि आपको यह जानने की जरूरत है कि कंपाइलर को भी यही बात बताएं, जैसा कि हास्केल और पायथन में है। BTW - अगर / स्विच / जबकि / C ++ में जो भी समान है, उन मामलों को रोकने में मदद करता है जहां इंडेंटेशन भ्रामक है - LHS नीचे एक दृश्य स्कैन आपको बताता है कि हर ओपन-ब्रेस एक ब्रेस-ब्रेस से मेल खाता है और यह संकेत उन ब्रेसिज़ के अनुरूप है।
स्टीव 314

1
@ Steve314: नहीं, इंडेंटेशन बेमानी है। पाइथन और हास्केल में इंडेंटेशन भी गुमराह कर सकता है, (वन-ऑफ इंडेंटेशन या टेबुलर्स के बारे में सोचें), यह सिर्फ इतना है कि पार्सर भी गलत है। मुझे लगता है कि कोष्ठक लेखक और पार्सर के लिए एक उपकरण है, जबकि इंडेंटेशन लेखक और (मानव) पाठक के लिए एक उपकरण है। दूसरे शब्दों में, इंडेंटेशन एक टिप्पणी है, कोष्ठक वाक्यविन्यास हैं।
Svante

11

कोड तो बहुत अधिक कॉम्पैक्ट है। संपादक में आंदोलन वैसे भी एस-एक्सप्रेशन द्वारा होता है, इसलिए आपको संपादन के लिए उस स्थान की आवश्यकता नहीं है। कोड ज्यादातर संरचना और वाक्यों द्वारा पढ़ा जाता है - निम्नलिखित सीमांकक द्वारा नहीं।


आपसे जवाब पाने के लिए क्या सम्मान है :) धन्यवाद।
चिरोन

एस-एक्सप्रेशन से कौन सा संपादक चलता है? अधिक विशेष रूप से, मुझे यह कैसे vimकरना है?
hasen

2
@HasenJ आपको vimacs.vim प्लगइन की आवश्यकता हो सकती है । : पी
मार्क सी

5

Lispers, तुम्हें पता है, द्वेषपूर्वक bletcherous यह हो सकता है के रूप में, वहाँ है एक निश्चित जेई NE sais quoi दूसरे उदाहरण के लिए:

(defn defer-expensive [cheap expensive]
  (if-let [good-enough (force cheap)]
    good-enough
    (force expensive)
  )
)

सबसे पहले, मैं इस तरह से बोलने के लिए खाद के स्रोत पर उंगली नहीं डाल सकता था, और तब मुझे एहसास हुआ कि यह एक ट्रिगर को याद कर रहा है:

(defn defer-expensive [cheap expensive]      
  (if-let [good-enough (force cheap)]
    good-enough   ;   )
    (force expensive) 
  )
)

देखा!

मैं अब अपने लिस्प गैंगस्टर पकड़ का अभ्यास करने जा रहा हूं!


2
यह सबसे मजेदार और सबसे कम जवाब में से एक है जो मैंने इस साइट पर देखा है। मैंने अपनी टोपी उतारी।
byxor

0

मेरे मामले में मुझे स्क्रीन स्पेस की बर्बादी के लिए समर्पित लाइनें मिलीं, और जब आप सी में कोड लिखते हैं तो शैली भी होती है

if (pred) {
   printf("yes");
   ++yes_votes;
}

अंतरिक्ष को बचाने के लिए लोग "अगर" की एक ही पंक्ति में शुरुआती ब्रेस क्यों लगाते हैं, और क्योंकि यह "यदि" पहले से ही अपनी लाइन है, तो यह अपनी खुद की लाइन को बेमानी लगता है।

आप अंत में कोष्ठक को एक साथ रखकर उसी परिणाम तक पहुँचते हैं। सी में अजीब लगेगा क्योंकि अर्धविराम में बयान समाप्त हो जाते हैं और कोष्ठक की जोड़ी इस तरह नहीं खुलती है

{if (pred)
    printf("yes");
}

यह अंत में ब्रेसिंग ब्रेस की तरह है, जगह से बाहर दिखता है। यह इस तरह खुलता है

if (pred) {
    printf("yes");
}

आपको '{' और '}' द्वारा ब्लॉक और इसकी सीमाओं के बारे में स्पष्ट जानकारी देना

और एक एडिटर की मदद से जो कोष्ठक से मेल खाता है, जैसे कि वेम करता है, आप अंत तक जा सकते हैं, जहाँ सभी कोष्ठक पैक किए जाते हैं और आसानी से उनके माध्यम से चलते हैं और सभी खुलने वाले परनों से मेल खाते हैं और नेस्टेड लिस्प रूप देखते हैं

(defn defer-expensive [cheap expensive]
    _(if-let [good-enough (force cheap)]
    good-enough
    (force expensive)_))

आप अपने कर्सर को बीच में समापन पैरा में रख सकते हैं और यदि आइए-आइए हाइलाइट किया गया हो, तो उसके खुलने वाले परन को रख सकते हैं।

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